Rust Option
Rust doesn’t have null. If a value might be missing, that’s expressed directly in the type using Option. It feels like extra ceremony at first, but it closes off an entire category of bugs — the “null reference” that’s caused countless crashes in other languages.
What Option looks like
Section titled “What Option looks like”Option is an enum with two variants:
enum Option<T> { Some(T), // a value is present None, // no value}You’ve actually already seen this — .get() on a vector and .get() on a HashMap both return an Option.
Creating an Option
Section titled “Creating an Option”fn main() { let has_value: Option<i32> = Some(5); let no_value: Option<i32> = None;
println!("{:?}", has_value); println!("{:?}", no_value);}Output:
Some(5)NoneHandling an Option with match
Section titled “Handling an Option with match”The safe way to get the value out is match — Rust forces you to handle both cases, so you can’t accidentally forget the “missing” case:
fn main() { let age: Option<i32> = Some(30);
match age { Some(value) => println!("Age is {value}"), None => println!("No age given"), }}A realistic example
Section titled “A realistic example”fn find_user(id: u32) -> Option<&'static str> { if id == 1 { Some("Alice") } else { None }}
fn main() { match find_user(1) { Some(name) => println!("Found: {name}"), None => println!("User not found"), }
match find_user(99) { Some(name) => println!("Found: {name}"), None => println!("User not found"), }}Output:
Found: AliceUser not foundInstead of returning null or throwing when a user isn’t found, the function’s return type itself tells every caller “this might not find anything” — and the compiler won’t let them ignore that possibility.
Shortcuts: unwrap_or and unwrap
Section titled “Shortcuts: unwrap_or and unwrap”For simple cases, a full match can feel like overkill. A couple of shortcuts:
fn main() { let age: Option<i32> = None;
let value = age.unwrap_or(0); // fall back to 0 if there's no value println!("{value}");}There’s also .unwrap(), which gives you the value directly — but panics (crashes) if it’s None:
let age: Option<i32> = Some(30);let value = age.unwrap(); // fine here, since age is SomePractice
Section titled “Practice”1. First even number
Section titled “1. First even number”Write fn first_even(numbers: &[i32]) -> Option<i32> that returns the first even number in the slice, or None if there isn’t one. Print the result for [3, 7, 8, 10] with match, and for [1, 3, 5] with .unwrap_or(0). Hint: loop over the slice and return Some(n) as soon as n % 2 == 0; after the loop, return None.
Show solution
fn first_even(numbers: &[i32]) -> Option<i32> { for &n in numbers { if n % 2 == 0 { return Some(n); } } None}
fn main() { match first_even(&[3, 7, 8, 10]) { Some(n) => println!("First even: {n}"), None => println!("No even numbers"), }
let fallback = first_even(&[1, 3, 5]).unwrap_or(0); println!("With fallback: {fallback}");}Output:
First even: 8With fallback: 02. Look up a setting
Section titled “2. Look up a setting”Make a HashMap of settings that only contains "volume" set to 80. Then loop over the keys "volume" and "brightness" and print the value if it exists, or a “not set” message if it doesn’t. Hint: .get(key) on a HashMap returns an Option, so you can match on it directly.
Show solution
use std::collections::HashMap;
fn main() { let mut settings = HashMap::new(); settings.insert("volume", 80);
for key in ["volume", "brightness"] { match settings.get(key) { Some(value) => println!("{key} = {value}"), None => println!("{key} is not set"), } }}Output:
volume = 80brightness is not setOption<T>represents a value that might or might not be present — Rust has nonull.Some(value)holds something;Nonemeans nothing is there.matchis the safe way to handle both cases; the compiler won’t let you forget one..unwrap_or(default)gives you a fallback;.unwrap()panics if the value isNone— use it sparingly.
Quick check
Section titled “Quick check”Quick check
1. What does Rust use instead of null for a value that might be missing?
2. What happens when you call .unwrap() on a None value?
3. What does age.unwrap_or(0) do when age is None?
4. Why is match considered the safe way to get a value out of an Option?
5. Which methods mentioned on this page already return an Option?
Score: 0 / 5
Read more
Section titled “Read more”- The Option Enum and Its Advantages Over Null Values — The Rust Book: the official explanation of why Rust uses
Optioninstead ofnull. std::option— standard library docs: an overview of everything you can do with anOption, including handy methods likemap,and_thenandis_some.- Option & unwrap — Rust by Example: short runnable examples of
match,unwrapand when a panic happens. Option<T>— std docs: the full list of methods, each with a tiny example you can copy.