我的枚举类型定义为
enum MyEnum {
Foo(SomeType),
Bar(SomethingElse),
Baz(YetAnotherThing),
...
}
我经常需要在Result
- 返回函数的上下文中匹配单个案例。更具体地说,我写这样的代码:
impl MyEnum {
fn as_foo(&self) -> Result<&SomeType, Error> {
if let MyEnum::Foo(x) = y {
Ok(&x)
} else {
Err(MismatchError)
}
}
fn as_bar(&self) -> Result<&SomethingElse, Error> {
...
}
...
}
以后我可以做
let x = myenum.as_foo()?
而不是更麻烦的
if let MyEnum::Foo(x) = myenum {
...
} else {
return Err(MismatchError);
}
当然,有一种更有效的方法来获得这种效果,而不是手工为每种可能的变体编写方法?语言中是否有某种东西,或者我应该研究自己写的宏?
我不清楚如何处理有多个字段或有命名字段的情况。前者可能通过一个元组?后者我总是可以通过引入中间结构来减少。
答案 0 :(得分:1)
您可以使用简单的访问者宏来执行此操作:
macro_rules! try_unpack {
($variant:path, $value:expr) => {
if let $variant(x) = $value {
x
} else {
return Err(MismatchError)
}
}
}
struct SomeType;
struct SomethingElse;
struct YetAnotherThing;
enum MyEnum {
Foo(SomeType),
Bar(SomethingElse),
Baz(YetAnotherThing)
}
struct MismatchError;
fn test(x: MyEnum) -> Result<i32, MismatchError> {
let y: SomethingElse = try_unpack!(MyEnum::Bar, x);
return 42;
}