You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用Rust语法糖实现更简洁的状态机?

Rust中更简洁的鼠标状态机实现

在C++这类C系语言中,我习惯用if else语句配合枚举实现状态机,通过判断当前状态执行状态转换,比如这段处理鼠标输入的示例代码:

if(current_left_state == GLFW_PRESS && !left_pressed)
{
    left_pressed = true;
    return MouseInputState::LEFT_DOWN;
}
if(current_left_state == GLFW_PRESS && left_pressed)
{
    left_pressed = true;
    return MouseInputState::LEFT_DRAG;
}
if(current_left_state == GLFW_RELEASE && left_pressed)
{
    left_pressed = false;
    return MouseInputState::LEFT_UP;
}
if(current_right_state == GLFW_PRESS && !right_pressed)
{
    right_pressed = true;
    return MouseInputState::RIGHT_DOWN;
}

现在我尝试用Rust实现相同逻辑,但感觉自己写的代码还有优化空间,想借助Rust的语法糖让实现更简洁。我目前的Rust代码如下:

MouseState::NoAction =>
{
    if *button == glfw::MouseButtonLeft && *action == glfw::Action::Press
    {
        return MouseState::LeftDown;
    }
    if *button == glfw::MouseButtonRight && *action == glfw::Action::Press
    {
        return MouseState::RightDown;
    }
    return MouseState::NoAction;
}
MouseState::LeftDown =>
{
    if *button == glfw::MouseButtonLeft && *action == glfw::Action::Release
    {
        return MouseState::LeftUp;
    }
    return MouseState::LeftDrag;
}
MouseState::LeftDrag =>
{
    if *button == glfw::MouseButtonLeft && *action == glfw::Action::Release
    {
        return MouseState::LeftUp;
    }
    return MouseState::LeftDrag;
}
MouseState::LeftUp =>
{
    if *button == glfw::MouseButtonLeft && *action == glfw::Action::Press
    {
        return MouseState::LeftUp;
    }
    return MouseState::NoAction;
}

优化后的实现方案

Rust的match表达式天生适合状态机场景,结合模式匹配可以大幅简化状态转换逻辑,以下是优化后的代码:

// 定义完整的鼠标状态枚举
enum MouseState {
    NoAction,
    LeftDown,
    LeftDrag,
    LeftUp,
    RightDown,
    // 可根据需求补充RightDrag、RightUp等状态
}

fn update_mouse_state(current_state: MouseState, button: glfw::MouseButton, action: glfw::Action) -> MouseState {
    use MouseState::*;
    use glfw::{MouseButton, Action};

    match (current_state, button, action) {
        // 从无动作状态触发的转换
        (NoAction, MouseButtonLeft, Action::Press) => LeftDown,
        (NoAction, MouseButtonRight, Action::Press) => RightDown,
        
        // 左键按下/拖拽状态下,松开左键则转到抬起状态
        (LeftDown | LeftDrag, MouseButtonLeft, Action::Release) => LeftUp,
        // 左键按下后,未松开则保持拖拽状态
        (LeftDown, _, _) => LeftDrag,
        
        // 左键抬起状态下,再次按下左键保持抬起状态,否则回到无动作
        (LeftUp, MouseButtonLeft, Action::Press) => LeftUp,
        (LeftUp, _, _) => NoAction,
        
        // 其他未覆盖的情况,保持原状态
        (state, _, _) => state,
    }
}

优化点说明

  • 元组模式匹配:将当前状态、鼠标按钮、动作打包成元组进行匹配,避免嵌套if,逻辑结构更直观
  • 多状态合并匹配:用|合并具有相同转换逻辑的状态(比如LeftDown和LeftDrag遇到左键松开都转到LeftUp),减少代码重复
  • 简化命名:通过use导入枚举成员,避免重复书写完整路径,代码更简洁
  • 默认分支处理:最后用通配符分支处理所有未明确定义的情况,直接返回原状态,无需冗余的判断和return

内容的提问来源于stack exchange,提问作者Makogan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 18:37:36