我有一个枚举类型定义为

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);
}

当然,有比通过为每种可能的变体手写方法更有效的方法了吗?语言中已经有一些东西,还是我应该研究编写自己的宏?

我不清楚如何处理多个字段或命名字段的情况。前者可能通过元组?我总是可以通过介绍中介结构来减少后者。

最佳答案

您可以使用一个简单的访问器宏来做到这一点:

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;
}

关于enums - 在Rust中将单个枚举变量映射到结果的惯用方式是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42906376/

10-11 22:27
查看更多