【问题标题】:Is there a way to match on all variants of an enum in rust?有没有办法匹配 rust 中枚举的所有变体?
【发布时间】:2021-06-11 09:16:35
【问题描述】:

有没有与此等价的东西:

enum ABC {
    A(u32),
    B(i32),
    C(f64),
}

fn main() {
    let abc = ABC::A(42);

    match abc {
        _(foo) => foo,
    }
}

我问的原因是,有时我想为不同的可能类型使用枚举,但大多数情况下我需要以完全相同的方式处理枚举变体中的数据。

【问题讨论】:

  • 您能否提供一个示例,说明您是如何“以完全相同的方式”处理它们的?
  • 看起来您应该将类​​型与数据分开,即您应该将当前枚举替换为同时具有值​​字段和“类型”字段的结构,这将是一个没有值的枚举跨度>
  • 一个例子是在哈希图中,我不能使用多种类型的值(和键)。所以我使用枚举作为值,然后通过键访问它们之后,我想要的就是使用枚举中的数据,同样的方式
  • @DenysSéguret 我不明白那会怎样,你能提供一个插图吗?
  • 在新的上下文中,您可能需要一个特征并将其应用于 u32、i32、64,但这个新问题太模糊,无法以一般方式回答。

标签: rust enums


【解决方案1】:

如果您想匹配所有可能的变体并执行常见操作,您可以 为它写一个宏,减少代码重复:

enum ABC {
    A(u32),
    B(i32),
    C(f64),
}

#[macro_use]
macro_rules! per_letter {
    ($val:expr, $pattern:pat => { $res:expr }) => (
        match $val {
            $crate::ABC::A($pattern) => $res,
            $crate::ABC::B($pattern) => $res,
            $crate::ABC::C($pattern) => $res,
        }
    )
}

impl ABC {
    pub fn print_inner(&self) {
        per_letter!(self, letter => {println!("{}", letter)});
    }
    pub fn print_quad(&self) {
        per_letter!(self, letter => {println!("{}", *letter**letter)});
    }
}

请注意,这是有限的。如果不将它们包装在枚举中,则不能有多种可能的返回类型。但如果您的内部类型共享一个通用功能,它仍然很有用。

fn main() {
    let foo = ABC::A(2);
    foo.print_inner();
    foo.print_quad();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-17
    • 1970-01-01
    • 2017-12-07
    • 1970-01-01
    • 2010-09-14
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    相关资源
    最近更新 更多