How to use Option with pattern matching

Use match, if let, or let...else to safely handle Option values by distinguishing between Some and None cases.

Use the match expression to destructure Option values into Some and None arms, binding the inner value to a variable in the Some arm. This allows you to handle the absence of a value explicitly while extracting the data when present.

fn plus_one(x: Option<i32>) -> Option<i32> {
    match x {
        None => None,
        Some(i) => Some(i + 1),
    }
}

Alternatively, use if let for concise control flow when you only care about one variant:

fn describe_state_quarter(coin: Coin) -> Option<String> {
    if let Coin::Quarter(state) = coin {
        Some(format!("{state:?}"))
    } else {
        None
    }
}

For early returns, use the let ... else pattern to extract the value or return immediately:

fn describe_state_quarter(coin: Coin) -> Option<String> {
    let Coin::Quarter(state) = coin else {
        return None;
    };
    Some(format!("{state:?}"))
}