英文:
Rust: Match two enum variants in one arm, binding field of one variant using Option?
问题
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 });
}
This is the neatest alternative I know of so far:
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 => (),
}
}
英文:
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 });
}
This is the neatest alternative I know of so far:
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 => (),
}
}
答案1
得分: 3
你可以使用 |
将两个变体的 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:?}");
英文:
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:?}");
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论