针对元组的模式匹配

问题描述

我正试图与由解构的枚举变量构造的元组匹配,如下所示:

enum Enum {
  Var {
    field1: Option<String>,field2: Option<String>
  }
}

let var = Enum::Var {
  field1: Some("aaa".to_string()),field2: None
}

match var {
  Enum::Var {field1,field2} => {
    match (field1,field2) {
      (Some("aaa".to_string()),None) => (),_ => panic!()
    }
  }
  _ => panic!()
}

但是,我收到错误消息

error: expected one of `)`,`,`...`,`..=`,`..`,or `|`,found `.`
  --> src/parser/test_admonitions.rs:61:22
   |
61 |         (Some("aaa".to_string()),None) => {}
   |                      ^
   |                      |
   |                      expected one of `)`,or `|`
   |                      help: missing `,`

error: aborting due to 1 prevIoUs error

这是为什么?为什么我不能与元组匹配?

解决方法

为什么不能与元组匹配?

您可以匹配一个元组。

您不能对任意表达式进行匹配,模式是一种受限制的语法。

检查元组的第一个元素是否为"aaa"(或更普遍地匹配非平凡条件)的正确方法是使用模式卫士

match (field1,field2) {
    (Some(a),None) if a == "aaa" => (),_ => panic!()
}

此外,不需要通过元组进行间接调用,模式具有“深度”,因此您可以直接在结构上执行相同的操作:

match var {
    Enum::Var {field1: Some(a),field2: None} if a == "aaa" => {
    }
    _ => panic!()
}
,

除了@Masklinn所示的比赛后卫之外,您还可以使用Option::as_deref()Option<String>转换为Option<&str>,并与后者进行匹配:

match var {
    Enum::Var { field1,field2 } => match (field1.as_deref(),field2.as_deref()) {
        (Some("aaa"),None) => (),_ => panic!(),},}