在一只手臂中匹配两个枚举变体,使用Option绑定一个变体的字段?

问题描述 投票:0回答:1

我想在一个匹配臂中匹配枚举的两个变体。每个字段中有一个字段是“相同”的,这意味着它具有相同的类型、名称和语义。 (下面示例中的

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 => (),
    }
}
rust enums pattern-matching
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:?}");
© www.soinside.com 2019 - 2024. All rights reserved.