Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Match

Match

  • match control flow construct allows to compare a value against a series of patterns and execute code based on which pattern matches.
  • Pattern can be made up of literal values, variable names, wildcards, etc..
  • match compares resultant value of an expression against the pattern of each arm and executes the code if the pattern matches.
enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter,
}

fn value_in_cents(coin: Coin) -> u8 {
    match coin {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter => 25,
    }
} 

Patterns that bind to values

  • match arms can bind to the parts of the values that match the pattern
#[derive(Debug)] // so we can inspect the state in a minute
enum UsState {
    Alabama,
    Alaska,
    // --snip--
}

enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter(UsState),
}

fn value_in_cents(coin: Coin) -> u8 {
    match coin {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter(state) => {
            println!("State quarter from {state:?}!");
            25
        }
    }
}

The Option match pattern

  • match asrms must be exhaustive
    fn plus_one(x: Option<i32>) -> Option<i32> {
        match x {
            None => None, // leaving out this arm will return a compilation error "non-exhaustive" petterns
            Some(i) => Some(i + 1),  // i binds to the value contained in Some, e.g. i = 5
        }
    }

    let five = Some(5);
    let six = plus_one(five);
    let none = plus_one(None);

Catch-all patterns

  • Allows to take special actions for a few particular values and default action for all others
  • Catch-all pattern should be last as the patterns are evaluated in order
let dice_roll = 9;
    match dice_roll {
        3 => add_fancy_hat(),
        7 => remove_fancy_hat(),
        other => move_player(other), // catch-all pattern
    }

    fn add_fancy_hat() {}
    fn remove_fancy_hat() {}
    fn move_player(num_spaces: u8) {}
  • if catch-all value is not needed, we can use _ instead:
    let dice_roll = 9;
    match dice_roll {
        3 => add_fancy_hat(),
        7 => remove_fancy_hat(),
        _ => reroll(),
    }

    fn add_fancy_hat() {}
    fn remove_fancy_hat() {}
    fn reroll() {}
  • if there is no code to execute for given pattern we can use unit type ()
    let dice_roll = 9;
    match dice_roll {
        3 => add_fancy_hat(),
        7 => remove_fancy_hat(),
        _ => (),
    }

    fn add_fancy_hat() {}
    fn remove_fancy_hat() {}