R

Pattern Matching

Rust syntax guide

Controlling flow with match expressions

Pattern Matching

Controlling flow with match expressions

Rust pattern matching (rust)
        
          #[derive(Debug)]
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 with values
#[derive(Debug)]
enum UsState {
    Alabama,
    Alaska,
}

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

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

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

// Matching with if let (concise)
fn print_coin(coin: Coin2) {
    if let Coin2::Quarter(state) = coin {
        println!("State quarter from {:?}!", state);
    } else {
        println!("Not a state quarter");
    }
}

// Matching ranges
fn categorize_number(n: i32) {
    match n {
        0 => println!("Zero"),
        1..=9 => println!("Single digit"),
        10..=99 => println!("Double digit"),
        100..=999 => println!("Triple digit"),
        _ => println!("Large number"),
    }
}

// Matching structs
struct Point {
    x: i32,
    y: i32,
}

fn match_point(point: Point) {
    match point {
        Point { x: 0, y: 0 } => println!("Origin"),
        Point { x: 0, y } => println!("On y-axis at {}", y),
        Point { x, y: 0 } => println!("On x-axis at {}", x),
        Point { x, y } => println!("Point ({}, {})", x, y),
    }
}

// Matching with guards
fn number_info(n: i32) {
    match n {
        n if n < 0 => println!("Negative"),
        n if n % 2 == 0 => println!("Even positive"),
        n if n % 2 == 1 => println!("Odd positive"),
        _ => unreachable!(),
    }
}

// Matching vectors
fn match_vector(vec: &Vec<i32>) {
    match vec.as_slice() {
        [] => println!("Empty vector"),
        [x] => println!("Vector with one element: {}", x),
        [x, y] => println!("Vector with two elements: {}, {}", x, y),
        [x, y, rest @ ..] => println!("Vector: {}, {}, and {} more", x, y, rest.len()),
        _ => println!("Large vector"),
    }
}

fn main() {
    let coin = Coin::Quarter;
    println!("Coin value: {} cents", value_in_cents(coin));

    let coin2 = Coin2::Quarter(UsState::Alaska);
    println!("Coin2 value: {} cents", value_in_cents2(coin2));

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

    println!("five: {:?}, six: {:?}, none: {:?}", five, six, none);

    print_coin(Coin2::Quarter(UsState::Alabama));
    print_coin(Coin2::Penny);

    categorize_number(42);
    categorize_number(0);
    categorize_number(1000);

    let point = Point { x: 10, y: 20 };
    match_point(point);

    number_info(-5);
    number_info(4);
    number_info(7);

    let empty_vec = vec![];
    let one_vec = vec![1];
    let two_vec = vec![1, 2];
    let many_vec = vec![1, 2, 3, 4, 5];

    match_vector(&empty_vec);
    match_vector(&one_vec);
    match_vector(&two_vec);
    match_vector(&many_vec);
}
        
      

Explanation

Rust match expression is powerful for control flow, allowing you to compare a value against a series of patterns and execute code based on which pattern matches. It is exhaustive, ensuring all cases are handled.

Common Use Cases

  • Handling different enum variants
  • Deconstructing complex data structures
  • Implementing state machines
  • Error handling with Result and Option

Related Rust Syntax

Master Pattern Matching in Rust

Understanding pattern matching is fundamental to writing clean and efficient Rust code. This comprehensive guide provides you with practical examples and detailed explanations to help you master this important concept.

Whether you're a beginner learning the basics or an experienced developer looking to refresh your knowledge, our examples cover real-world scenarios and best practices for using pattern matching effectively in your Rust projects.

Key Takeaways

  • Handling different enum variants
  • Deconstructing complex data structures
  • Implementing state machines