I'd like to match two variants of an enum in one match arm. There is one field that is "the same" in each, meaning that it has the same type, name and semantic meaning. (field0: i32
in the example below.) I'd like to bind a local &mut i32
to field0
of the given variant. One variant also has a field that is not "shared" by the other. (field1: String
in the example.) This I would like to bind to a local Option<&mut String>
. Is there a neat way to do this?
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 });
}
You can make field0
of both variants into the same binding with |
.
match value {
Variant0 { field0, .. } | Variant1 { field0 } => println!("{field0}"),
_ => (),
}
However, your other requirement of field1
doesn't really fit into this syntax, so you need to do it manually. If you only needed an &
reference, you could do it in two match expressions, but that is unlikely to be any prettier.
let (field0, field1) = match value {
Variant0 { field0, field1 } => (field0, Some(field1)),
Variant1 { field0 } => (field0, None),
Variant2 => return,
};
println!("{field0}, {field1:?}");