Option Type

Using the Option<T> enum instead of null values.

Intermediate⏱️ 30 min📚 Prerequisites: 1

Option Type

The Option<T> is a built-in enum that allows a value to be something or nothing.

Option Definition

RUST
enum Option<T> {
    Some(T),
    None,
}

This is Rust's way of handling null values - type-safe and explicit.

Usage

RUST
let some_number = Some(5);
let some_string = Some("a string");
let absent_number: Option<i32> = None;

Option Methods

unwrap()

RUST
let x = Some(5).unwrap();  // 5
let y = None.unwrap();      // PANIC!

expect()

RUST
let x = Some(5).expect("Cannot be None");

unwrap_or()

RUST
let x = Some(5).unwrap_or(0);  // 5
let y = None.unwrap_or(0);     // 0

is_some() / is_none()

RUST
if some_option.is_some() {
    // Has value
}

Using Match

RUST
match some_option {
    Some(value) => println!("{}", value),
    None => println!("No value"),
}

Code Examples

Basic Option

Creating and using Option

RUST
fn main() {
    let some_number = Some(5);
    let some_string = Some("a string");
    let absent_number: Option<i32> = None;
    println!("some_number: {:?}", some_number);
    println!("absent_number: {:?}", absent_number);
}

Explanation:

Option<T> can be Some(T) or None. Some contains the value, None indicates no value.

Unwrap Methods

Extracting Option values

RUST
fn main() {
    let some_value = Some(42);
    let none_value: Option<i32> = None;
    let x = some_value.unwrap_or(0);
    let y = none_value.unwrap_or(0);
    println!("x: {}, y: {}", x, y);
    let z = some_value.expect("Cannot be None");
    println!("z: {}", z);
}

Explanation:

unwrap_or safely returns a value, or the default if None. expect is similar but panics if None.

Matching Option

Handling Option with match expression

RUST
fn divide(numerator: f64, denominator: f64) -> Option<f64> {
    if denominator != 0.0 {
        Some(numerator / denominator)
    } else {
        None
    }
}
fn main() {
    let result = divide(10.0, 2.0);
    match result {
        Some(value) => println!("Result: {}", value),
        None => println!("Division by zero!"),
    }
    let invalid = divide(10.0, 0.0);
    match invalid {
        Some(value) => println!("Result: {}", value),
        None => println!("Division by zero!"),
    }
}

Explanation:

The match expression handles Option values in a type-safe way. All cases must be explicitly handled.

Exercises

Option Function

Write a function that returns an Option<i32>!

Medium

Starter Code:

RUST
fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    let result = find_number(&numbers, 3);
    println!("{:?}", result);
}