我正在尝试定义宏以简化枚举的创建 可以转换为/来自str:
macro_rules! define_enum_with_str_values {
($Name:ident { $($Variant:ident => $StrVar:expr),* $(,)* }) => {
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum $Name {
$($Variant),*,
}
impl Into<&'static str> for $Name {
fn into(self) -> &'static str {
match self {
$($Name::$Variant => $StrVar),*
}
}
}
impl FromStr for $Name {
type Err = BaseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let obj = match s {
$($StrVar => $Name::$Variant),*
};
Ok(obj)
}
}
}
}
define_enum_with_str_values!(Foo { Aa => "a", Bb => "b" });
此代码未编译,因为我没有定义'_'
规则,
但如果我定义'_'
规则:
impl FromStr for $Name {
type Err = BaseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let obj = match s {
$($StrVar => $Name::$Variant),*
_ => {}
};
Ok(obj)
}
}
我遇到了这样的编译错误:
error: expected one of `!`, `,`, `.`, `::`, `?`, `{`, `}`, or an operator, found `_`
--> foo.rs:74:25
|
73 | $($StrVar => $Name::$Variant),*
| - expected one of 8 possible tokens here
74 | _ => {}
| ^ unexpected token
...
82 | define_enum_with_str_values!(Foo { Aa => "a", Bb => "b" });
| ----------------------------------------------------------- in this macro invocation
答案 0 :(得分:2)
考虑当展开该宏时会发生什么。有问题的match
将如下所示:
let obj = match s {
"a" => Foo::Aa , "b" => Foo::Bb
_ => {}
};
请注意"b"
和_
之间缺少逗号。最简单的解决方法是确保每个臂后都有一个逗号:
let obj = match s {
$($StrVar => $Name::$Variant,)*
_ => return Err(BaseError)
};