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 SomeOption<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.