如何在匹配期间不显式绑定枚举变体的字段?

  • 本文关键字:枚举 绑定 字段 rust
  • 更新时间 :
  • 英文 :


假设我有一个枚举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),
_ => {}
}

我认为以下内容可能会有所帮助:

fn f(e: &E) {
match e {
E::A {x1, .. } => {dbg!(x1);},
_ => {}
};
}

E::A {x1,..}bad @ E::A {x1:x1, ..}的缩写,它将bad.x1的值绑定到正文范围内可用的新局部变量x1

您可以使用带有可变参数的宏,因此编译器会键入长名称两次,并且它会绑定您需要的参数。您可以在宏中调用您的函数而不是 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.
}
_ => {}
}
};
}

在锈操场上尝试一下

最新更新