在 Rust 模式匹配中将变量绑定到文字

Bind variable to literal in Rust pattern matching

我有一个用 Rust 编写的状态机,它需要对两个状态执行相同的操作。

两种状态都是枚举的变体,但包含不同数量的元素。

match self.state {
    RunState::ACCUMULATE(byte, count) | RunState::ESCAPE(count) => todo!(), 
    _ => todo!()
}

该示例是无效的源代码,因为 byte 未在所有模式中绑定。

这可以通过将 byte 绑定到第二个模式中的文字零来解决,但我不知道如何存档。

我目前正在分别匹配这两种模式,这会导致我想避免的代码重复。

感谢您的关注。

模式旨在根据匹配的值按结构和绑定变量进行匹配。它不是为了引入任意绑定而设计的。您应该使用单独的 match 分支,如果您担心重复,也许可以使用辅助函数:

match self.state {
    RunState::ACCUMULATE(byte, count) => helper(byte, count),
    RunState::ESCAPE(count) => helper(0, count), 
    ...
}

或者您可以为 enum 引入一个函数,该函数 returns 需要的值如:

impl RunState {
    fn to_parts(&self) -> (u8, usize) { // or Option<(u8, usize)> if its not applicable to all
        match self.state {
            RunState::ACCUMULATE(byte, count) => (byte, count),
            RunState::ESCAPE(count) => (0, count), 
            ...
        }
    }
}

您可以通过 not 在任何分支中绑定 byte 来解决您的问题:

match self.state {
    RunState::ACCUMULATE(_, count) | RunState::ESCAPE(count) => todo!(), 
    _ => todo!()
}

如果在 ACCUMULATE 的情况下需要 byte,那么严格来说两者的代码并不相同,但这可以通过额外的步骤来提取 byte:

match self.state {
    RunState::ACCUMULATE(_, count) | RunState::ESCAPE(count) => {
        let byte = if let RunState::ACCUMULATE (byte, _) = self.state { byte } else { 0 };
        todo!()
    }, 
    _ => todo!()
}