Hey, I'm not sure I fully understand why we can't have "simple" expressions in match clauses. For example,
fn main() {
let x: usize = 0;
match x {
0 => println!("x is zero"),
1 => println!("x is one"),
_ => println!("x is neither 0 or 1")
}
}
Compiles just fine, but if I change it to
fn main() {
let x: usize = 0;
match x {
0 => println!("x is zero"),
0+1 => println!("x is one"),
_ => println!("x is neither 0 or 1")
}
}
Suddenly I get
ERROR!
error: expected a pattern, found an expression
|
5 | 0+1 => println!("x is one"),
| ^^^ not a pattern
|
= note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
With two quick solution options - using a match arm guard, or defining a const. Both solution work, but why can't I leave it as-is and let the compiler create the const (at compile time)? Is there a reason why "1" and "0+1" are not considered the same for this case?
0 + 1 is an expression. The evaluation of an expression can be used as a pattern discriminator in a match guard:
match x {
0 => println!("x is zero"),
_ if x == 0+1 => println!("x is one"),
_ => println!("x is neither 0 or 1")
}
See the linked book page in the error message for what constitutes a pattern:
Literals
Destructured arrays, enums, structs, or tuples
Variables
Wildcards
Placeholders
These items are valid for patterns, expressions are not. I do not know the specific reason for the limitation. It may be syntactic or semantic ambiguity. For instance, how would a pattern like foo + bar be matched? These are two variables that acquire the value being matched.