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)
Four letters.
Discussion
Loading…