我想在一个匹配臂中匹配一个枚举的两个变体。每个字段中有一个字段是“相同的”,这意味着它具有相同的类型、名称和语义。 (下面示例中的
field0: i32
。)我想将本地&mut i32
绑定到给定变体的field0
。一个变体也有一个不被另一个变体“共享”的字段。 (示例中的field1: String
。)我想绑定到本地Option<&mut String>
。有没有一个巧妙的方法来做到这一点?
enum Enum {
Variant0 { field0: i32, field1: String },
Variant1 { field0: i32 },
Variant2,
}
fn mutate(value: &mut Enum) {
match value {
// Hopefully some pattern matching magic
// to get a local &mut i32 and a local
// Option<&mut String>.
}
}
fn main() {
mutate(&mut Enum::Variant0 {
field0: 123,
field1: "hello".to_string(),
});
mutate(&mut Enum::Variant1 { field0: 456 });
}
这是迄今为止我所知道的最巧妙的选择:
fn mutate(value: &mut Enum) {
match value {
Enum::Variant0 { field0, .. } | Enum::Variant1 { field0 } => {
// Mutate *field0 here.
if let Enum::Variant0 { field1, .. } = value {
// Mutate *field1 here.
}
}
Enum::Variant2 => (),
}
}
您可以将两个变体的
field0
与|
进行相同的绑定。
match value {
Variant0 { field0, .. } | Variant1 { field0 } => println!("{field0}"),
_ => (),
}
但是,您对
field1
的其他要求并不真正符合此语法,因此您需要手动完成。如果你只需要一个 &
引用,你可以用两个匹配表达式来完成,但这不太可能更漂亮。
let (field0, field1) = match value {
Variant0 { field0, field1 } => (field0, Some(field1)),
Variant1 { field0 } => (field0, None),
Variant2 => return,
};
println!("{field0}, {field1:?}");