Consider this Rust code that tries to parse a number from a string and handle errors:
fn parse_number(s: &str) -> Result{ s.parse:: ().map_err(|_| "Parse error".to_string()) } fn main() { match parse_number("42") { Ok(n) => println!("Number: {}", n), Err(e) => println!("Error: {}", e), } }
What will this program print when run?
fn parse_number(s: &str) -> Result<i32, String> { s.parse::<i32>().map_err(|_| "Parse error".to_string()) } fn main() { match parse_number("42") { Ok(n) => println!("Number: {}", n), Err(e) => println!("Error: {}", e), } }
Think about what parse:: returns when given a valid number string.
The string "42" parses successfully to the integer 42, so Ok(42) is returned. The match prints "Number: 42".
Look at this Rust code snippet:
fn main() {
let v = vec![1, 2, 3];
println!("{}", v[10]);
}What happens when you run this program?
fn main() {
let v = vec![1, 2, 3];
println!("{}", v[10]);
}Think about how Rust handles accessing vector elements with an invalid index.
Rust vectors panic at runtime if you access an index outside their bounds. This causes a runtime panic with an index out of bounds message.
When writing a Rust library, which error handling approach is best practice?
Think about how libraries should behave to be flexible for users.
Libraries should return Result to let users decide how to handle errors. Panicking or unwrapping forces behavior and reduces flexibility.
Consider this Rust function:
fn get_first_char(s: &str) -> Result{ let c = s.chars().next().ok_or("Empty string".to_string())?; Ok(c) } fn main() { match get_first_char("") { Ok(c) => println!("First char: {}", c), Err(e) => println!("Error: {}", e), } }
What will this program print?
fn get_first_char(s: &str) -> Result<char, String> { let c = s.chars().next().ok_or("Empty string".to_string())?; Ok(c) } fn main() { match get_first_char("") { Ok(c) => println!("First char: {}", c), Err(e) => println!("Error: {}", e), } }
What does ok_or do when the iterator is empty?
The string is empty, so chars().next() returns None. ok_or converts this to an Err with message "Empty string". The ? operator returns the error early, so the Err is matched and printed.
Examine this Rust code snippet:
fn read_file() -> Result{ let content = std::fs::read_to_string("file.txt").unwrap(); Ok(content) }
Why is this not recommended when used in a function that returns Result?
fn read_file() -> Result<String, std::io::Error> { let content = std::fs::read_to_string("file.txt").unwrap(); Ok(content) }
Think about how to properly propagate errors in functions returning Result.
Using unwrap() forces a panic on error, which is not idiomatic in functions returning Result. Instead, the ? operator should be used to propagate errors gracefully.