What is Option<T>?
Rust doesn't have null. Instead, it gives you Option<T>, which explicitly says "this value might be here, or it might not." It's an enum with two variants: Some(value) and None. This forces you to handle the missing case โ no more null pointer exceptions sneaking into production.
fn main() {
let some_number: Option<i32> = Some(42);
let no_number: Option<i32> = None;
println!("{:?}", some_number);
println!("{:?}", no_number);
}
Try it Yourself ->
Unwrap and Its Dangers
You can use unwrap() to pull the value out of Some, but it panics if you try to unwrap None. It's useful for quick prototypes, but in production code, always handle the None case explicitly.
fn main() {
let number: Option<i32> = Some(5);
println!("{}", number.unwrap()); // prints 5
// This would panic:
// let nothing: Option<i32> = None;
// println!("{}", nothing.unwrap());
}
Try it Yourself ->
Match for Safe Handling
The proper way to handle an Option is with match. You check for Some and None explicitly, so the compiler knows you've considered both cases.
fn main() {
let number: Option<i32> = Some(10);
match number {
Some(n) => println!("The number is: {}", n),
None => println!("No number found"),
}
}
Try it Yourself ->
Chaining with map, unwrap_or, and and_then
Rust gives you powerful combinator methods to work with Option values without unwrapping. map transforms the inner value, unwrap_or provides a fallback, and and_then chains operations that might return None.
fn main() {
let x: Option<i32> = Some(5);
// map: transforms the inner value
let doubled = x.map(|v| v * 2);
println!("doubled: {:?}", doubled);
// unwrap_or: fallback value if None
let value = x.unwrap_or(0);
println!("value: {}", value);
// and_then: chain a function that returns Option
let result = x.and_then(|v| if v > 0 { Some(v * 10) } else { None });
println!("result: {:?}", result);
}
Try it Yourself ->