如何在匹配枚举变体时,不需要显式地绑定来访问该变体的字段?

9
假设我有一个枚举 E,它可能是自动生成的或不受我的控制,包含许多变量,每个变量都有若干字段。
enum E {
    A {
        x1: u8,
        x2: u8,
        x3: u8,
        // ...
        x9: u8,
    },
    B,
}

实际上,字段可能会更长,既难以记忆,也难以输入。我现在想编写针对(变体)`E` 的函数。然而,我很懒,不想重复自己,在析构枚举时明确声明每个使用的字段。
直觉上,我希望绑定运算符 `@` 可以在这里起作用,但它只绑定整个枚举 `e`,而不是给定的变体 `E::A`。
实现以下意图的最短/最优雅的方法是什么?
fn f(e: &E) {
    match e {
        bad @ E::A { .. } => dbg!(bad.x1),
        _ => {}
    }
}

*更新,因为这已经在两个答案中提出,我不想E::A { x1, .. }匹配,因为当需要多个具有较长名称的字段时,这将变得很烦琐。在下面的示例中,我必须在我的代码中两次输入some_other_field_with_an_impossibly_long_name(一次绑定它,一次使用它),而在假设的bad @ E::A情况下,我只需要输入它一次。

match e {
    E::A { some_field_with_a_long_name, some_other_field_with_an_impossibly_long_name, yet_another_field, .. } => dbg!(some_other_field_with_an_impossibly_long_name),
    _ => {}
}

3
也许这个提示表明这不会起作用:https://github.com/rust-lang/rust/issues/40666。 - CoronA
1
哈哈,谢谢!我想这就是这个问题的真正“答案” :( - left4bread
2个回答

1
我认为以下内容可能会有所帮助:
fn f(e: &E) {
  match e {
   E::A {x1, .. } => {dbg!(x1);},
    _ => {}
  };
}

E::A {x1,..}bad @ E::A {x1:x1, ..} 的简写,将 bad.x1 的值绑定到一个新的本地变量 x1 中,在主体作用域中可用。


谢谢,但是正如我在问题中所述,我不想显式地绑定 x1,...。 - left4bread
抱歉,你是对的,我误解了你的陈述。谢谢澄清。 - CoronA

1
您可以使用具有可变参数的宏,因此编译器会将长名称键入两次,并绑定所需数量的参数。您可以在宏中调用函数而不是println:
    f!(&e, x1);
    f!(&e, x2, x1);

macro_rules! f {
    ($e: expr, $( $name:ident ),+ ) => {
        match $e {
            E::A {   $($name),* , ..} => {
                println!("{:?}", &[$($name),*]); // call your function here.
            }
            _ => {}
        }
    };
}

Rust Playground上尝试一下吧


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接