rust 如何在嵌套对象中匹配String和str?

cgh8pdjw  于 2022-12-27  发布在  其他
关注(0)|答案(1)|浏览(107)

假设我有下面的Rust枚举:

enum Food {
    Fruit(String), // the String represents the food's name
    Vegitable(String),
}

如何测试一个函数实际生成的是苹果而不是香蕉?

例如,我想要一个类似下面的测试:

#[test]
fn is_correct_food() {
    let apple = Food::Fruit("Banana".to_string()); // comes from tested function
    assert!(matches!(apple, Food::Fruit("Apple".to_string())));
}

Playground link
当我运行上面的代码时,我得到了以下错误:

error: expected one of `)`, `,`, `...`, `..=`, `..`, or `|`, found `.`
 --> src/lib.rs:8:48
  |
8 |     assert!(matches!(apple, Food::Fruit("Apple".to_string())));
  |                                                ^
  |                                                |
  |                                                expected one of `)`, `,`, `...`, `..=`, `..`, or `|`
  |                                                help: missing `,`

在做了一些研究之后,我了解到发生这个错误是因为你不能在模式匹配语句中调用函数。如果我尝试把名字抽象成一个变量(以删除函数调用),测试就会通过,因为模式匹配。

#[test]
fn is_correct_food() {
    let apple = Food::Fruit("Banana".to_string()); // comes from tested function
    let name = "Apple".to_string();
    assert!(matches!(apple, Food::Fruit(name)));
}

Playground link

不良溶液

可以使用match语句从内容中取出变量。但是,在测试中应不惜一切代价避免逻辑。此外,我需要测试的实际对象要复杂得多,这将需要许多嵌套的match语句。因此,我希望避免类似以下测试的任何操作:

#[test]
fn is_correct_food() {
    let apple = Food::Fruit("Banana".to_string()); // comes from tested function
    match apple {
        Food::Fruit(name) => assert_eq!(name, "apple"),
        _ => panic!("should be a fruit"),
    }
}

相关问题

How to match a String against string literals?
对顶级字符串进行模式匹配。我希望在嵌套对象内部进行模式匹配。

zzlelutf

zzlelutf1#

就像您可以在匹配块中的模式后添加一个if(称为 match guard)一样,您也可以对matches!执行相同的操作:

matches!(apple, Food::Fruit(fruit) if fruit == "Apple")

matches!的文档中提到了此功能,并包含了一个演示该功能的示例。

相关问题