Rust Option
Option is a value that is either Some(value) or None. Its methods work with the value inside without a match for every step.
map changes the value inside
map runs your function only when a value is present. A None passes through untouched:
let name = Some("ada");
let loud = name.map(|n| n.to_uppercase());
println!("{loud:?}");and_then chains a step that can fail
When the next step itself returns an Option, and_then feeds the value straight through. The answer stays one layer flat:
let boosted = Some(4).and_then(|n| if n > 0 { Some(n * 10) } else { None });
println!("{boosted:?}");map would nest the box
The same step through map wraps its answer in a second Some — a box inside a box. That nesting is what and_then exists to avoid:
let boxed = Some(4).map(|n| if n > 0 { Some(n * 10) } else { None });
println!("{boxed:?}");filter can turn a Some into a None
filter keeps the value only when a test passes. This age fails the test, so the Option becomes empty:
let age = Some(15).filter(|a| *a >= 18);
println!("{age:?}");? leaves early on None
Inside a function that returns Option, ? hands the value out — or returns None at once when there is none. Sending the empty case onward like this is called propagation:
fn shout_first(word: Option<&str>) -> Option<String> {
let w = word?;
Some(w.to_uppercase())
}
let loud = shout_first(Some("hey"));
println!("{loud:?}");Example
fn find_user(id: u32) -> Option<&'static str> {
match id { 1 => Some("ada"), 2 => Some("grace"), _ => None }
}
fn main() {
let shout = find_user(2).map(|n| n.to_uppercase());
println!("{:?}", shout);
println!("{:?}", find_user(9).unwrap_or("guest"));
}Key points
- Every Option answers one question: is there a value inside, or not?
- Functions return Option instead of fake values like -1 or an empty string
In this example, find_user returns Some("grace") for id 2. Calling .map on it runs the function only because a value is present. The name becomes uppercase. The result is Some("GRACE"). For id 9, find_user returns None. unwrap_or("guest") steps in with the fallback, so the program prints "guest". No match was needed, and no empty box ever caused a crash.
Note
unwrap() also takes the value out.
unwrap() stops the program on None.
Keep it for quick tests and cases that truly cannot be empty.
Prefer unwrap_or in real code.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
Which method changes the value inside a Some and leaves None alone?