在 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!()
}
我有一个用 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!()
}