假设我有一个枚举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.
}
_ => {}
}
};
}
在锈操场上尝试一下