I want to store bitor pattern (e.g. 'a' | 'b' | 'c'
) as a constant so that I can reuse it in multiple match statements
if you code like this:
fn match_fn(a:u8)->bool{
match a{
b'a' | b'b'| b'c' => true,
_ => false,
}
}
then use a function to check them:
fn pattern(a:u8)->bool{
a == b'a' || a == b'b' || a == b'c'
}
fn match_tgt(a:u8)->bool{
match a {
x if pattern(x) => true,
_ => false,
}
}
You’ll lose exhaustivity checking, though.
To the OP: patterns in Rust aren’t "first-class citizens", just syntax, so you can’t store them in variables or similar. But you can write a macro that expands to a pattern if necessary:
macro_rules! chars {
() => { 'a' | 'b' }
}
Like we can store ranges, there should be a way to store patterns as well.
No, you actually can’t. As jdahlstrom said above, patterns are just syntax. They can’t be stored in variables. A stored value of type std::ops::Range
/RangeInclusive
/RangeFrom
etc. is not the same thing as a range pattern. This code (Playground):
const RANGE: std::ops::Range<u8> = 0..10;
fn f(n: u8) {
match n {
RANGE => println!("within range"),
_ => {},
}
}
doesn’t do what you think. It gives this error:
error[E0308]: mismatched types
--> src/lib.rs:5:9
|
1 | const RANGE: std::ops::Range<u8> = 0..10;
| -------------------------------- constant defined here
...
4 | match n {
| - this expression has type `u8`
5 | RANGE => println!("within range"),
| ^^^^^
| |
| expected `u8`, found `Range<u8>`
| `RANGE` is interpreted as a constant, not a new binding
|
= note: expected type `u8`
found struct `std::ops::Range<u8>`
help: you may want to move the range into the match block
|
5 | 0..10 => println!("within range"),
| ~~~~~
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` (lib) due to 1 previous error
RANGE
is not interpreted as a pattern in this case, but as a constant of type std::ops::Range<u8>
[1]. rustc even suggests changing it to the correct code that matches 0 ≤ n < 10
:
help: you may want to move the range into the match block | 5 | 0..10 => println!("within range"), | ~~~~~
RANGE
is actually a pattern, but one that matchesRange { start: 0, end: 10 }
↩︎