Option and Result
Search the catalogue for a title it does not hold. Type letters where a card number should go. Many languages answer with null or an exception that the caller may forget to handle. Rust has neither. It uses two ordinary enums, and the type system will not let you ignore them.
The rule
Maybe missing →
Option; might fail →Result. Handle both arms before use.
Both are enums from the standard library, always in scope:
enum Option<T> { Some(T), None }
enum Result<T, E> { Ok(T), Err(E) }Option<T>: a value that may be absent, with no reason needed.
fn find(shelf: &[Book], title: &str) -> Option<usize> {
shelf.iter().position(|b| b.title == title)
}Result<T, E>: an operation that can fail, and E says why.
let card: Result<u32, _> = "1042".parse::<u32>(); // Ok(1042)
let bad: Result<u32, _> = "10x2".parse::<u32>(); // Err(ParseIntError)An Option<u32> is not a u32. You cannot add to it or print it as a number until you open it:
match "10x2".parse::<u32>() {
Ok(card) => println!("lending to card {card}"),
Err(e) => println!("that is not a card number: {e}"),
}
if let Some(i) = find(&shelf, "Iron Tides") {
println!("found at position {i}");
}Handy methods instead of a full match:
unwrap_or(default): the value, or a fallback.input.parse::<u32>().unwrap_or(0).unwrap(): the value, or panic (crash) onNone/Err.expect("message"): likeunwrap, with your message in the panic.ok()turns aResultinto anOption;ok_or(err)goes the other way.
The shortcut
Ask: "If it isn't there, is that an error with a reason?" No reason needed → Option. A reason the caller should see → Result. Then choose how to open it: match or if let to handle, unwrap_or to default, ? (next lesson) to pass upward.
Parse the input
"1042".parse::<u32>()can fail with a reason, so it gives aResult.
The trap is unwrap() everywhere. It compiles, then crashes the first time real input is wrong.
Drills
Answer fast — trust the rule.
What are the two variants of Result<T, E>?
A catalogue search finds no match. Which return type fits best?
What does "10x2".parse::<u32>().unwrap() do?
What is "abc".parse::<u32>().unwrap_or(0)?
With let n: Option<u32> = Some(5);, why does n + 1 fail to compile?
Remember
Option=SomeorNone(maybe missing);Result=OkorErr(might fail, with a reason).- Ask "is absence an error with a reason?" Then open with
match,if let,unwrap_oror?. - Trap:
unwrapturns a handled case into a crash.
