Result
Some work can fail: reading a file, parsing text, dividing by zero. Rust does not hide this. A function that can fail returns a Result.
Result
Result<T, E> is an enum with two variants:
Ok(value)- it worked, and here is aT.Err(error)- it failed, and here is anEthat says why.
fn half(n: i32) -> Result<i32, String> { if n % 2 == 0 { Ok(n / 2) } else { Err(String::from("odd")) }}Matching a Result
Use match to handle both outcomes. You must cover both Ok and Err, or the code does not compile (E0004).
match half(7) { Ok(h) => println!("half is {h}"), Err(e) => println!("error: {e}"),}Parsing strings
"42".parse::<i32>() turns text into a number. The text might not be a number, so it returns Result<i32, ParseIntError>, not a plain i32. Parsing is strict: " 12" with a space fails.
let good = "42".parse::<i32>(); // Ok(42)let bad = "4x".parse::<i32>(); // Err(...)Result methods
You do not always need a full match:
r.unwrap_or(0)- the value, or0if it is anErr.r.ok()- turnsOk(v)intoSome(v)andErrintoNone.r.is_ok()-trueif it is anOk.r.map_err(f)- runs the functionfon the error and keeps theOkas it is.
It is like map on Option, but for the error.
fn label(code: i32) -> String { format!("error {code}")}let n = "x".parse::<i32>().unwrap_or(0); // 0let r: Result<i32, i32> = Err(404);let m = r.map_err(label); // Err("error 404")Remember
- A function that can fail returns
Result<T, E>. Okholds the value,Errholds the error.matchmust handle bothOkandErr.parsereturns aResult, so you must deal with the error.