#rust #pattern-matching
#Ржавчина #сопоставление шаблона
Вопрос:
Я пытаюсь сопоставить с кортежем, созданным из деконструированного варианта перечисления, подобного этому:
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
Почему это? Почему я не могу сопоставить с кортежем?
Ответ №1:
Почему я не могу сопоставить с кортежем?
Вы можете сопоставить с кортежем.
Чего вы не можете сделать, так это сопоставить с произвольными выражениями, шаблоны — это ограниченный синтаксис.
Правильный способ проверить, соответствует ли первый элемент кортежа "aaa"
(или, в более общем смысле, соответствует нетривиальному условию), — это использовать защиту шаблона:
match (field1, field2) {
(Some(a), None) if a == "aaa" => (),
_ => panic!()
}
кроме того, в косвенном обращении через кортеж нет необходимости, шаблоны имеют «глубину», поэтому вы можете сделать то же самое непосредственно со структурой:
match var {
Enum::Var {field1: Some(a), field2: None} if a == "aaa" => {
}
_ => panic!()
}
Ответ №2:
В дополнение к защите соответствия, как показано на моем @Masklinn, вы можете использовать Option::as_deref()
для преобразования Option<String>
в Option<amp;str>
и сопоставления с последним:
match var {
Enum::Var { field1, field2 } => match (field1.as_deref(), field2.as_deref()) {
(Some("aaa"), None) => (),
_ => panic!(),
},
}