Rust Pattern Matching and Match Expressions

Using Match Expressions for Control Flow:

Match Expressions:

The match keyword allows you to perform pattern matching.The two part composition of match is a pattern and an expression for evaluation if the pattern is met.

Example:

                    
fn main() {
    let number = 7;

    match number {
        1 => println!("One!"),
        2 => println!("Two!"),
        3 => println!("Three!"),
        4 | 5 | 6 => println!("Four, Five, or Six!"),
        7..=10 => println!("Seven to Ten!"),
        _ => println!("Something else!"),
    }
}
                    
                  
  • Patterns: Every pattern has the expression for its execution as well as the current binding value.
  • Wildcards: _ is a catch-all pattern that matches any value not covered by other patterns.
  • Ranges: 7..=10 matches any value from 7 to 10, inclusive.

Destructuring and Matching on Enums and Structs

Enums:

Enums, which are frequently paired with pattern matching to deal with variant types are a good example.

Example:

                    
enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

fn main() {
    let msg = Message::Move { x: 10, y: 20 };

    match msg {
        Message::Quit => println!("Quit"),
        Message::Move { x, y } => println!("Move to x: {}, y: {}", x, y),
        Message::Write(text) => println!("Write: {}", text),
        Message::ChangeColor(r, g, b) => println!("Change color to red: {}, green: {}, blue: {}", r, g, b),
    }
}
                    
                  
  • Destructuring: Message::Move { x, y } destructures the Move variant to access its fields.

Structs:

Structs can also be destructured in patterns.

Example:

                    
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let origin = Point { x: 0, y: 0 };

    match origin {
        Point { x, y } => println!("Point at ({}, {})", x, y),
    }

    let Point { x, y } = origin;
    println!("Destructured point at ({}, {})", x, y);
}
                    
                  
  • Struct Pattern: Point { x, y } destructures the struct to access its fields directly.

Destructuring in Function Parameters:

You can also use patterns directly in function parameters.

Example:

                    
fn print_coordinates(&(x, y): &(i32, i32)) {
    println!("Current location: ({}, {})", x, y);
}

fn main() {
    let point = (3, 5);
    print_coordinates(&point);
}
                    
                  
  • Function Parameters: &(x, y) destructures a tuple passed as a parameter.

Nested Patterns:

Patterns can be nested to match complex data structures.

Example:

                    
enum Message {
    Move { x: i32, y: i32 },
    Echo(String),
    ChangeColor { red: u8, green: u8, blue: u8 },
}

fn main() {
    let msg = Message::ChangeColor { red: 0, green: 255, blue: 127 };

    match msg {
        Message::Move { x, y } => println!("Move to x: {}, y: {}", x, y),
        Message::Echo(text) => println!("Echo: {}", text),
        Message::ChangeColor { red, green, blue } => println!("Change color to red: {}, green: {}, blue: {}", red, green, blue),
    }
}
                    
                  
  • Nested Destructuring: Message::ChangeColor { red, green, blue } accesses fields within the enum variant.

Rust patter matching lifts code readability and stability writhing about clear, expressive way to deal with different types of data and structures.