我有一个枚举:
enum Operation {
Add,
Subtract,
}
impl Operation {
fn from(s: &str) -> Result<Self, &str> {
match s {
"+" => Ok(Self::Add),
"-" => Ok(Self::Subtract),
_ => Err("Invalid operation"),
}
}
}
我想在编译时确保每个枚举变量都在 from
函数中处理。
为什么我需要这个?例如,我可能会添加一个 Product
操作,而忘记在 from
函数中处理这种情况:
enum Operation {
// ...
Product,
}
impl Operation {
fn from(s: &str) -> Result<Self, &str> {
// No changes, I forgot to add a match arm for `Product`.
match s {
"+" => Ok(Self::Add),
"-" => Ok(Self::Subtract),
_ => Err("Invalid operation"),
}
}
}
是否可以保证匹配表达式返回枚举的每个变体?如果不是,模仿这种行为的最佳方式是什么?
最佳答案
一个解决方案是使用宏生成整个枚举、变体和翻译臂:
macro_rules! operations {
(
$($name:ident: $chr:expr)*
) => {
#[derive(Debug)]
pub enum Operation {
$($name,)*
}
impl Operation {
fn from(s: &str) -> Result<Self, &str> {
match s {
$($chr => Ok(Self::$name),)*
_ => Err("Invalid operation"),
}
}
}
}
}
operations! {
Add: "+"
Subtract: "-"
}
通过这种方式添加变体很简单,而且您不会忘记解析。这也是一个非常干的解决方案。
可以很容易地使用您以后肯定需要的其他功能(例如反向翻译)来扩展此构造,并且您不必复制解析字符。
关于enums - 如何确保每个枚举变体都可以在编译时从特定函数返回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58715081/