Match guards in Rust - Time & Space Complexity
We want to see how using match guards affects the time it takes for a program to run.
Specifically, how the number of checks grows as the input gets bigger.
Analyze the time complexity of the following code snippet.
fn count_even_greater_than_five(numbers: &[i32]) -> usize {
let mut count = 0;
for &num in numbers {
match num {
n if n % 2 == 0 && n > 5 => count += 1,
_ => (),
}
}
count
}
This code counts how many numbers in a list are even and greater than five using a match with a guard.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping through each number in the list once.
- How many times: Exactly once for each number in the input list.
Each number is checked once with the match guard condition.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 checks |
| 100 | 100 checks |
| 1000 | 1000 checks |
Pattern observation: The number of checks grows directly with the input size.
Time Complexity: O(n)
This means the time to run grows in a straight line as the list gets bigger.
[X] Wrong: "Match guards make the code slower by adding extra loops or checks for each condition."
[OK] Correct: The match guard only adds a simple condition check inside the existing loop, so it does not add extra loops or multiply the work.
Understanding how match guards affect performance helps you write clear and efficient Rust code, a skill that shows you think about both correctness and speed.
"What if we added a nested loop inside the match guard to check something else? How would the time complexity change?"
Practice
What is the purpose of a match guard in Rust?
Solution
Step 1: Understand match guards
Match guards add extra conditions to patterns in a match, allowing more precise checks.Step 2: Compare options
Only To add an extra condition to a pattern in a match statement correctly describes adding extra conditions to patterns.Final Answer:
To add an extra condition to a pattern in a match statement -> Option AQuick Check:
Match guard = extra condition [OK]
- Thinking match guards replace match statements
- Confusing match guards with variable declarations
- Assuming match guards loop over patterns
Which of the following is the correct syntax for a match guard in Rust?
match x {
5 if x > 3 => println!("Greater than 3"),
_ => println!("Other")
}Solution
Step 1: Identify correct match guard syntax
Match guards usepattern if condition => expressionsyntax.Step 2: Check options
match x { 5 if x > 3 => println!("Greater than 3"), _ => println!("Other") } correctly placesif x > 3after the pattern 5.Final Answer:
match x { 5 if x > 3 => println!("Greater than 3"), _ => println!("Other") } -> Option CQuick Check:
Pattern if condition => action [OK]
- Placing if before the pattern
- Using if inside the match arm block
- Putting if after the expression
What will be the output of the following Rust code?
let num = 7;
match num {
n if n < 5 => println!("Less than 5"),
n if n <= 10 => println!("Between 5 and 10"),
_ => println!("Greater than 10"),
}Solution
Step 1: Evaluate match arms in order
num is 7, first guard checks if 7 < 5 (false), so skip.Step 2: Check second guard
7 <= 10 is true, so this arm runs and prints "Between 5 and 10".Final Answer:
Between 5 and 10 -> Option AQuick Check:
7 ≤ 10 matches second guard [OK]
- Assuming first guard matches 7
- Thinking all guards run
- Confusing output with compile error
Identify the error in this Rust code using match guards:
let x = 10;
match x {
n if n > 5 => println!("Greater than 5"),
n if n > 8 => println!("Greater than 8"),
_ => println!("Other"),
}Solution
Step 1: Analyze guard order and coverage
The first guard matches all n > 5, so it includes all n > 8 as well.Step 2: Identify unreachable code
The second guard is never reached because the first guard catches those values first.Final Answer:
The second guard is unreachable because the first guard covers all cases greater than 5 -> Option DQuick Check:
First guard shadows second guard [OK]
- Ignoring unreachable code warnings
- Thinking guards can overlap safely
- Misunderstanding guard evaluation order
Given a list of integers, write a Rust match expression with match guards to print:
- "Small" if the number is less than 10
- "Medium" if the number is between 10 and 20 (inclusive)
- "Large" if the number is greater than 20
Which of the following match arms correctly implements this logic for a variable n?
Solution
Step 1: Check conditions for each size category
"Small" is for n < 10, "Medium" for 10 ≤ n ≤ 20, "Large" for n > 20.Step 2: Verify each match arm
match n { x if x < 10 => println!("Small"), x if x >= 10 && x <= 20 => println!("Medium"), _ => println!("Large"), } correctly usesx < 10,x >= 10 && x <= 20, and wildcard for others.Final Answer:
match n { x if x < 10 => println!("Small"), x if x >= 10 && x <= 20 => println!("Medium"), _ => println!("Large"), } -> Option BQuick Check:
Guards match exact ranges [OK]
- Using wrong comparison operators
- Overlapping ranges causing unreachable arms
- Missing inclusive bounds for medium range
Ready to prove it?
Pass the test and this pattern moves unknown
