Handling errors with match in Rust - Time & Space Complexity
When we handle errors using match in Rust, we want to know how the time to run the code changes as input grows.
We ask: How much work does the program do when matching on results?
Analyze the time complexity of the following code snippet.
fn process_numbers(nums: &[i32]) {
for &num in nums {
match num.checked_mul(2) {
Some(val) => println!("Double: {}", val),
None => println!("Overflow for {}", num),
}
}
}
This code doubles each number if possible, or prints an overflow message if not.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping through each number in the input slice.
- How many times: Once for every number in the input list.
Each number causes one check and one print. More numbers mean more work.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 checks and prints |
| 100 | About 100 checks and prints |
| 1000 | About 1000 checks and prints |
Pattern observation: The work grows directly with the number of items.
Time Complexity: O(n)
This means the time to run grows in a straight line as the input list gets bigger.
[X] Wrong: "Matching on errors makes the code slower in a way that depends on the error type."
[OK] Correct: Matching just checks the result once per item, so it grows only with the number of items, not the error details.
Understanding how error handling affects performance helps you write clear and efficient Rust code, a skill useful in many real projects.
"What if we replaced the loop with recursion? How would the time complexity change?"
Practice
match statement do when used with a Result type in Rust?Solution
Step 1: Understand the purpose of
ThematchwithResultmatchstatement is used to check the two possible states of aResult:Okfor success andErrfor failure.Step 2: Recognize handling of both cases
By matching onOkandErr, you can write code to handle success and error separately, making the program safe and clear.Final Answer:
It checks if the result isOkorErrand lets you handle each case. -> Option DQuick Check:
match with Result = handle Ok or Err [OK]
- Thinking match fixes errors automatically
- Assuming match converts Result to string
- Ignoring error cases in match
Result<T, E> named res and print "Success" if Ok?Solution
Step 1: Check pattern matching syntax
The correct syntax usesOk(_)andErr(_)with arrows=>to separate patterns from actions.Step 2: Verify the printed messages
match res { Ok(_) => println!("Success"), Err(_) => println!("Error") } prints "Success" onOkand "Error" onErr, which matches the question requirement.Final Answer:
match res { Ok(_) => println!("Success"), Err(_) => println!("Error") } -> Option BQuick Check:
Correct match syntax = match res { Ok(_) => println!("Success"), Err(_) => println!("Error") } [OK]
- Omitting arrows => in match arms
- Not using parentheses for Ok(_) or Err(_)
- Swapping success and error messages
let res: Result<i32, &str> = Err("fail");
match res {
Ok(val) => println!("Value: {}", val),
Err(e) => println!("Error: {}", e),
}Solution
Step 1: Identify the Result variant
The variableresis assignedErr("fail"), so it represents an error.Step 2: Match arms execution
Thematchwill go to theErr(e)arm and print "Error: fail".Final Answer:
Error: fail -> Option AQuick Check:
Err variant prints error message [OK]
- Confusing Err with Ok variant
- Expecting value instead of error message
- Ignoring the match arms
let res: Result<i32, &str> = Ok(10);
match res {
Ok(val) => println!("Value: {}", val),
Err => println!("Error occurred"),
}Solution
Step 1: Check match arm patterns
In Rust, match arms forResultmust pattern match with parentheses, soErrshould beErr(_)orErr(e).Step 2: Identify the syntax error
The code usesErrwithout parentheses, which is invalid syntax and causes a compile error.Final Answer:
Missing parentheses after Err in match arm -> Option AQuick Check:
Err pattern needs parentheses () [OK]
- Writing Err without parentheses
- Confusing semicolon placement
- Changing Result type unnecessarily
Result<i32, String>. Inside, you try to parse a string to an integer. Using match, how do you handle the parsing result to return Ok(number) if successful or Err with a custom message if it fails?Solution
Step 1: Understand parse returns Result
Theparse()method returnsResult<T, E>, so matching on it lets us handle success and failure.Step 2: Return matching Result from function
OnOk(n), returnOk(n)to propagate success. OnErr(_), returnErrwith a custom error message as aString.Final Answer:
match s.parse() { Ok(n) => Ok(n), Err(_) => Err(String::from("Parse failed")) } -> Option CQuick Check:
Match parse Result to return Ok or custom Err [OK]
- Swapping Ok and Err returns
- Returning raw values instead of Result
- Using string literals instead of String in Err
Ready to prove it?
Pass the test and this pattern moves unknown
