13 / 20 · Day 5
Day 5 · Concept 13

Result & Option

Two enums in the standard library that replace null pointers and exceptions. Option<T> = Some(T) or None. Result<T,E> = Ok(T) or Err(E). The compiler forces you to handle both variants. No "I forgot to check for null".


1 · Option — replacing null

rust src/main.rs
fn first_word(s: &str) -> Option<&str> {
    s.split_whitespace().next()
}

fn main() {
    let r1 = first_word("hello world");
    match r1 {
        Some(w) => println!("first: {}", w),
        None    => println!("empty"),
    }

    // Common helpers
    println!("{}", first_word("hi there").unwrap());       // panics if None
    println!("{}", first_word("").unwrap_or("(empty)"));   // default
    println!("{:?}", first_word("ok").map(|s| s.to_uppercase())); // transform
}

2 · Result — replacing exceptions

rust src/main.rs
fn divide(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 {
        Err("division by zero".into())
    } else {
        Ok(a / b)
    }
}

fn main() {
    match divide(10.0, 2.0) {
        Ok(r) => println!("ok: {}", r),
        Err(e) => println!("err: {}", e),
    }

    // Or chain
    let outcome = divide(10.0, 0.0).unwrap_or(-1.0);
    println!("outcome: {}", outcome);
}

3 · The combinators worth memorising

MethodWhat it does
.unwrap()Extract; panic on None/Err. Prototype only.
.expect("msg")Like unwrap, with a custom panic message.
.unwrap_or(default)Extract or use the default.
.unwrap_or_else(|| ...)Lazily compute the default.
.map(|x| ...)Transform the Ok/Some value.
.and_then(|x| ...)Chain another Result/Option.
.ok()Result<T,E> → Option<T>.
? operatorPropagate Err / None (next concept).

4 · Common mistakes

  • .unwrap() in production. Fine in tests. In production, prefer ? to propagate.
  • Ignoring Result. fn() -> Result<T,E> with the call discarded — the compiler warns. Use let _ = only when you really mean it.
  • Using Option for "might fail with reason". That's Result. Option is "might not have a value".

5 · When it clicks

  • You feel uncomfortable when someone returns null in another language.
  • The combinator chain (.map().and_then().unwrap_or()) feels natural.
  • You distinguish "no value" (Option) from "operation failed" (Result) without thinking.
Found this useful?