Match. With Rust's match, we choose from a selection of expressions, and run the code from the matching expression. Only one path can be taken—a default case is possible.
Some details. We can assign a value to the result value of match—in this way match is like a function. And Options (Some) can be used in expressions.
First example. To begin, we use both the match keyword, and the if-else keywords to implement selection statements in Rust. The result of the 2 approaches here is the same.
Version 1 We use match—if the ID if 5, we print a certain message. In this program, the ID is 10, so we match the default ("_") case.
Version 2 The if-else block here contains the same logic as the match keyword. The code seems to be less elegant, and longer.
fn main() {
let id = 10;
// Version 1: use match.
match id {
5 => println!("Id is 5"),
_ => println!("Id is not 5")
}
// Version 2: use if-else.
if id == 5 {
println!("Id is 5");
} else {
println!("Id is not 5");
}
}Id is not 5
Id is not 5
Assign example. Match can be used like an expression—it can be assigned to a variable. Here we have the string "rust," and we match that string in a match statement.
Result The bool "true" is used, and this value is stored in the memory location of the "compiled" variable.
fn main() {
let language = "rust";
// Assign a boolean based on the result of match.// ... Default is false.
let compiled = match language {
"rust" => true,
"java" => true,
_ => false
};
println!("COMPILED: {}", compiled);
}COMPILED: true
Example, Some. In Rust, many functions (like find) return an Option. We can use pattern matching to match the possible options returned.
Tip Find here returns Some(1), which is matched in the match statement, and a message is printed.
fn main() {
let letters = "abc";
// Use match on an Option result.// ... Use Some() to match the returned option with its enclosed value.
match letters.find("b") {
Some(5) => println!("Found at index 5"),
Some(1) => println!("Found at index 1"),
_ => println!("Not found")
}
}Found at index 1
Multiple values. In Rust the match statement can handle groups of values in a single block. We match 2 cases in a single block by using the vertical bar.
Info The values 0 and 10 are grouped together in this example. So the result is the same for values 0 and 10.
fn main() {
let value = 10;
let result = match value {
5 => "Five",
0 | 10 => "Zero or ten",
_ => "Unknown"
};
// Print result.
println!("VALUE = {}, RESULT = {}", value, result);
}VALUE = 10, RESULT = Zero or ten
Ranges. Inclusive ranges can be used as match conditions. Here we try to match the values 4 through 10 (including 10) in the first match condition.
And The value is 11, so it is matched by the second condition which is from 11 up to and including 20.
fn main() {
let value = 11;
// Match with ranges.
let result = match value {
4..=10 => "Four through ten",
11..=20 => "Eleven through twenty",
_ => "Default"
};
println!("{}", result);
}Eleven through twenty
String match. We cannot match on a String, but we can match on a str reference. To convert a String to a str reference, we can just take its reference.
Here The test() function matches on a str reference, and returns a usize value. In main() we call test() in 2 separate ways.
fn test(value: &str) -> usize {
// Match on string literal.
match value {
"bird" => 10,
"frog" => 20,
"cat" => 30,
_ => 0
}
}
fn main() {
// Use the match function.
println!("FROG: {}", test("frog"));
// Build up a string and pass the reference to it.
let mut temp = String::new();
temp.push_str("cat");
println!("CAT: {}", test(&temp));
}FROG: 20
CAT: 30
Matches macro. In Rust, macros end with the exclamation mark. We can rewrite a match expression that returns true and false with the matches macro.
fn main() {
if let Ok(element) = "100".parse() {
// True if 50, 100 or 150.
let result = matches!(element, 50 | 100 | 150);
println!("{}", result);
}
}true
Non-exhaustive error. In Rust a match must handle all possible values of a type. If it does not, we will get a non-exhaustive patterns compile-time error.
fn main() {
let value = 0;
// Must add the default case here to compile.
match value {
1 => println!("ONE")
}
}error[E0004]: non-exhaustive patterns: i32::MIN..=0_i32 and 2_i32..=i32::MAX not covered
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
note: the matched value is of type i32
Match, if benchmark. Is match faster than if? The compiler (and LLVM) may be able to optimize match better than if. In this benchmark, we have 2 versions of the same logic.
Version 1 This version of the code, get_match(), returns a value based on a match statement.
Version 2 Here we do the same logic in an if-statement. The same values are returned as in version 1.
Result The match statement is about twice as fast as the if-statement. It is worth using match on numbers when possible.
Tip It is important to use parse() to get the max and top values, so the compiler does not optimize out the loops.
use std::time::*;
fn get_match(x: usize) -> usize {
match x {
1 | 2 | 3 => 1,
4 => 2,
5 => 3,
6 | 7 | 8 => 4,
_ => 0
}
}
fn get_if(x: usize) -> usize {
if x == 1 || x == 2 || x == 3 {
1
} else if x == 4 {
2
} else if x == 5 {
3
} else if x == 6 || x == 7 || x == 8 {
4
} else {
0
}
}
fn main() {
if let Ok(max) = "100000000".parse() {
if let Ok(top) = "10".parse() {
let mut sum1 = 0;
let mut sum2 = 0;
// Version 1: use match.
let t0 = Instant::now();
for _ in 0..max {
for i in 0..top {
sum1 += get_match(i);
}
}
println!("{}", t0.elapsed().as_millis());
// Version 2: use if.
let t1 = Instant::now();
for _ in 0..max {
for i in 0..top {
sum2 += get_if(i);
}
}
println!("{}", t1.elapsed().as_millis());
println!("{} = {}", sum1, sum2);
}
}
} 510 ms (match)
1049 ms (if)
2000000000 = 2000000000
A summary. Often we use match with Option and Some, but we do not need to. Match statements can replace if-statements, and the resulting code is often clearer.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Jan 29, 2022 (grammar).