Соответствие кортежей с несколькими возможными значениями

Поскольку соответствие наборов с диапазонами работает, я надеялся, что что-то подобное будет также работать с альтернативами:

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

Есть ли элегантное решение для этого или нужно либо "развернуть" альтернативы, либо прибегнуть к цепочке if/else if вместо соответствия шаблону?

Ответ 1

Альтернативы не являются частью синтаксиса для шаблонов; a | b не является шаблоном. Альтернативы могут использоваться только для комбинирования шаблонов в руке match (они не доступны в выражениях if let и while 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")
}

Охранники - это произвольные выражения (которые должны оцениваться как 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")
}