将枚举与 Struct::default() 值匹配/错误:预期的元组结构或元组变体,找到关联函数“A::default”

ANi*_*120 1 rust

我想匹配具有结构值的枚举。当我匹配枚举时,似乎需要为枚举字段提供一个值(如果有)。我想将此值设置为 A::default() 并引用此默认值,但这给了我错误: expected tuple struct or tuple variant, found associated function `A::default。我该如何解决这个问题?操场

use std::default::Default;

struct A {
    val_1: i32,
    val_2: i32,
    val_3: Vec<String>,
}

impl Default for A {
    fn default() -> A {
        A {
            val_1: 0,
            val_2: 0,
            val_3: vec!["Hello".to_string()],
        }
    }
}

struct B {
    val_1: i32,
    val_2: i32,
    val_3: A,
}

impl Default for B {
    fn default() -> B {
        B {
            val_1: 0,
            val_2: 0,
            val_3: A::default(),
        }
    }
}

enum Ops {
    OpA { config: A },
    OpB { config: B },
}

struct Mast {
    pub OpType: Ops,
}
fn main() {
    let myop = Mast {
        OpType: Ops::OpA {
            config: A::default(),
        },
    };

    match myop.OpType {
        Ops::OpA{ config: A::default() } => {
            println!("{}", "got OpA"),
            println!("{}", A::default().val_1),

        }//<--'expected tuple struct or tuple variant, found associated function `A::default`'
        Ops::OpB{ config: B::default() } => println!("{}", "got OpB"),
    }
}
Run Code Online (Sandbox Code Playgroud)

Apl*_*123 5

您不关心结构体字段值,因此使用..忽略该值:

match myop.OpType {
    Ops::OpA {..} => println!("{}", "got OpA"),
    Ops::OpB {..} => println!("{}", "got OpA"),
}
Run Code Online (Sandbox Code Playgroud)

如果你想将config字段提取到变量中,比如说foo,那么你可以这样做:

match myop.OpType {
    Ops::OpA {config: foo} => println!("OpA: {}", foo),
    Ops::OpB {config: foo} => println!("OpB: {}", foo),
}
Run Code Online (Sandbox Code Playgroud)

这也是旧代码不起作用的原因:因为模式匹配将模式提取到变量中,并且它不检查值是否相等。

如果你想改变它,那么通过以下方式匹配它ref

match myop.OpType {
    Ops::OpA {config: ref mut foo} => *foo = A::default(),
    Ops::OpB {config: ref mut foo} => *foo = B::default(),
}
Run Code Online (Sandbox Code Playgroud)

这也需要myop如此mut。还有一个简写形式 ,{config}它将扩展为{config: config}

match myop.OpType {
    Ops::OpA {ref mut config} => *config = A::default(),
    Ops::OpB {ref mut config} => *config = B::default(),
}
Run Code Online (Sandbox Code Playgroud)

也可以看看: