Consider this Rust function that reads a number from a string and doubles it. What will be printed when calling main()?
fn double_number(s: &str) -> Result<i32, std::num::ParseIntError> {
let n: i32 = s.parse()?;
Ok(n * 2)
}
fn main() {
match double_number("10") {
Ok(val) => println!("Result: {}", val),
Err(e) => println!("Error: {}", e),
}
}Remember that ? returns the error early if parsing fails, otherwise continues.
The string "10" parses successfully to 10, then doubled to 20, so the output is Result: 20.
What happens when running this Rust code?
fn parse_and_double(s: &str) -> Result<i32, std::num::ParseIntError> {
let n: i32 = s.parse()?;
Ok(n * 2)
}
fn main() {
match parse_and_double("abc") {
Ok(val) => println!("Result: {}", val),
Err(e) => println!("Error: {}", e),
}
}What happens if parsing fails with ? inside a function returning Result?
The string "abc" cannot be parsed to an integer, so s.parse()? returns an error which is propagated. The error message is "invalid digit found in string".
Examine this Rust code snippet. Why does it fail to compile?
fn try_parse(s: &str) {
let n: i32 = s.parse()?;
println!("Number: {}", n);
}
fn main() {
try_parse("42");
}The ? operator can only be used in functions that return Result or Option.
The function try_parse returns nothing (()), but uses ?. This is invalid because ? needs the function to return a compatible Result or Option type.
Choose the code snippet that correctly uses the ? operator to propagate errors.
Remember that ? can only be used on a Result or Option value directly.
Option A correctly uses ? on the Result from parse() and returns Ok(n). Option A returns i32 but uses ? which requires a Result return type. Option A misuses unwrap() before ?. Option A tries to use ? inside Ok() which is invalid syntax.
Given this Rust code, how many times will the error be propagated if the input string is invalid?
fn step1(s: &str) -> Result<i32, std::num::ParseIntError> {
let n = s.parse()?;
Ok(n)
}
fn step2(s: &str) -> Result<i32, std::num::ParseIntError> {
let n = step1(s)?;
Ok(n * 2)
}
fn main() {
match step2("not_a_number") {
Ok(val) => println!("Value: {}", val),
Err(e) => println!("Error: {}", e),
}
}Think about how the ? operator passes errors up the call stack.
The error from s.parse() in step1 is propagated up by ? to step2, which also uses ? to propagate it further to main. So the error is propagated once per function call up the chain.