iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Option

Option<T> is Rust’s null. Two variants — Some(T) and None — the compiler forces you to handle both before you can use the value.

Option methods + pattern matching

EXAMPLE
fn first_word(s: &str) -> Option<&str> {
    s.split_whitespace().next()
}

fn main() {
    let s = "hello world";

    // 1) Pattern match — explicit, exhaustive
    match first_word(s) {
        Some(w) => println!("first: {w}"),
        None    => println!("empty"),
    }

    // 2) if let — for one-arm matches
    if let Some(w) = first_word(s) {
        println!("got {w}");
    }

    // 3) Default value
    let w = first_word("").unwrap_or("default");
    let w = first_word("").unwrap_or_else(|| String::from("computed").as_str());
    let w = first_word("").unwrap_or_default();      // T's Default::default()

    // 4) Map — transform inside the Option (lazy)
    let len: Option<usize> = first_word(s).map(|w| w.len());
    let upper: Option<String> = first_word(s).map(str::to_uppercase);

    // 5) and_then (flatMap) — chain Option-returning ops
    let n: Option<i32> = first_word(s).and_then(|w| w.parse().ok());

    // 6) Filter — keep Some only if predicate true
    let positive = first_word(s)
        .and_then(|w| w.parse::<i32>().ok())
        .filter(|&n| n > 0);

    // 7) Combine — both Some, or None
    let a: Option<i32> = Some(1);
    let b: Option<i32> = Some(2);
    let sum = a.zip(b).map(|(x, y)| x + y);          // Some(3)

    // 8) ?-operator inside Option-returning fn
    fn first_char_upper(s: &str) -> Option<char> {
        let w = s.split_whitespace().next()?;        // returns None if missing
        w.chars().next().map(|c| c.to_ascii_uppercase())
    }

    // 9) Panicking — only when you can prove it's safe
    let n = first_word("non-empty").unwrap();        // panics if None
    let n = first_word(s).expect("input was empty"); // panics WITH a message

    // 10) Convert to Result
    let r: Result<&str, &str> = first_word(s).ok_or("empty");
}

Why it matters

? propagates None up the call stack just like it does Err. It’s the cleanest way to chain fallible operations without an explicit match at every step.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
fn first_word(s: &str) -> Option<&str> {
    s.split_whitespace().next()
}

match first_word("hi there") {
    Some(w) => println!("{w}"),
    None => println!("empty"),
}
Try it Yourself »

Exercise

Wrap a value to indicate presence.

(42)

Test yourself

Q1. Rust models "possibly missing" via…
Q2. The two variants of Option are…
Q3. Unwrap or use a default with…

Discussion

Loading…