title: Option
Option<T> is Rust’s way of expressing a value that might not exist. It replaces null from other languages — but unlike null, you can’t accidentally use an Option as if it were a real value. The compiler forces you to handle both cases.
What it looks like
Option is an enum with two variants:
enum Option<T> {
Some(T), // there is a value
None, // there is no value
}Creating an Option
let some_number: Option<i32> = Some(42);
let no_number: Option<i32> = None;In practice, Rust infers the type so you rarely need to annotate it:
let name = Some(String::from("Alice"));
let missing: Option<String> = None; // type needed here since there's no value to infer fromUsing match to handle both cases
fn describe(value: Option<i32>) {
match value {
Some(n) => println!("got {n}"),
None => println!("got nothing"),
}
}The compiler won’t let you ignore None — match must be exhaustive.
if let — a shorter alternative to match
When you only care about the Some case:
let value = Some(42);
if let Some(n) = value {
println!("got {n}");
}Common methods
You’ll use these constantly:
let value: Option<i32> = Some(42);
value.is_some(); // true
value.is_none(); // false
value.unwrap(); // returns 42, panics if None — avoid in production
value.unwrap_or(0); // returns 42, falls back to 0 if None
value.unwrap_or_else(|| expensive_default()); // lazy fallback
// transform the inner value without unwrapping
value.map(|n| n * 2); // Some(84)
// chain operations that also return Option
value.and_then(|n| if n > 0 { Some(n) } else { None });The ? operator
In a function that returns Option, you can use ? to return None early if a value is missing:
fn first_even(numbers: &[i32]) -> Option<i32> {
let first = numbers.first()?; // returns None if slice is empty
if first % 2 == 0 { Some(*first) } else { None }
}? is shorthand for “if this is None, return None from the whole function.”
Why not just use null?
With null, any value in your program might secretly be null, and the compiler won’t warn you — you only find out at runtime with a crash. With Option, the type system makes it explicit: an Option<String> might be missing, a plain String is guaranteed to exist. You can never forget to handle the missing case.