匹配具有多个可能值的元组

Tho*_*s W 11 tuples pattern-matching rust

由于与范围匹配的元组起作用,我希望类似的东西也适用于替代方案:

match x {
    (1, 1) => println!("A"),
    (1, 2 ... 3) => println!("B"),   // ranges work
    (2 | 5, 4 | 6) => println!("C"), // this doesn't
    _ => println!("D")
}
Run Code Online (Sandbox Code Playgroud)

是否有一个优雅的解决方案,或者是否必须"展开"替代方案或采用链式if/ else if而不是模式匹配?

Fra*_*gné 12

替代品不是模式语法的一部分; a | b不是一种模式.替代只能被用于图案在一个结合match臂(它们不是在可用的if letwhile let表达式要么).

解决方法是使用警卫:

match x {
    (1, 1) => println!("A"),
    (1, 2 ... 3) => println!("B"),
    (a, b) if (a == 2 || a == 5) &&
              (b == 4 || b == 6) => println!("C"),
    _ => println!("D")
}
Run Code Online (Sandbox Code Playgroud)

防护是任意表达式(必须评估为a bool),因此它们可以调用函数.

match x {
    (1, 1) => println!("A"),
    (1, 2 ... 3) => println!("B"),
    (a, b) if [2, 5].contains(&a) &&
              [4, 6].contains(&b) => println!("C"),
    _ => println!("D")
}
Run Code Online (Sandbox Code Playgroud)

  • @Kroltan:我上面的代码为 `(2, 4)`、`(5, 4)`、`(2, 6)` 和 `(5, 6)` 打印了 `C` ... (2认同)

kmd*_*eko 8

Rust 1.53开始,模式匹配已扩展为允许嵌套|模式。因此,原始提供的示例在这方面按原样编译(Playground 链接):

match x {
    (1, 1) => println!("A"),
    (1, 2..=3) => println!("B"),
    (2 | 5, 4 | 6) => println!("C"),
    _ => println!("D")
}
Run Code Online (Sandbox Code Playgroud)

...对于包含范围,在 2021 版中已弃用,取而代之..=