How to Use Pattern Matching In Rust?

9 minutes read

Pattern matching in Rust allows the developer to match the structure of data against predefined patterns and execute corresponding code blocks. It is a powerful feature that simplifies data extraction and helps in handling different cases efficiently.


To use pattern matching, you can utilize the match statement. It enables you to compare a value against a series of patterns and execute code based on the match.


Here's a general structure of a match statement in Rust:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
match value {
    pattern1 => {
        // code to execute if pattern1 matches
    },
    pattern2 => {
        // code to execute if pattern2 matches
    },
    _ => {
        // code to execute if none of the patterns match
    }
}


In the above code, value is the value being matched against the patterns. Each pattern can be a constant, a variable, or a combination of different patterns.


Here are a few examples of how pattern matching can be used in Rust:

  1. Matching an exact value:
1
2
3
4
5
6
let x = 5;

match x {
    5 => println!("The value is 5"),
    _ => println!("Not a match"),
}


  1. Matching a range of values:
1
2
3
4
5
6
7
let age = 20;

match age {
    0..=17 => println!("You are a minor"),
    18..=64 => println!("You are an adult"),
    _ => println!("You are a senior citizen"),
}


  1. Extracting values from an enum:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
enum Shape {
    Circle(f64),
    Square(f64),
    Rectangle(f64, f64),
}

let shape = Shape::Rectangle(5.0, 6.0);

match shape {
    Shape::Circle(radius) => println!("Circle with radius {}", radius),
    Shape::Square(side_length) => println!("Square with side length {}", side_length),
    Shape::Rectangle(length, width) => println!("Rectangle with length {} and width {}", length, width),
}


These are just basic examples, but pattern matching can be used in many more complex scenarios in Rust. It provides a concise and expressive way to handle different cases and can greatly enhance your code readability and maintainability.

Best Rust Books to Read in 2024

1
Programming Rust: Fast, Safe Systems Development

Rating is 5 out of 5

Programming Rust: Fast, Safe Systems Development

2
Hands-on Rust: Effective Learning through 2D Game Development and Play

Rating is 4.9 out of 5

Hands-on Rust: Effective Learning through 2D Game Development and Play

3
Rust for Rustaceans: Idiomatic Programming for Experienced Developers

Rating is 4.8 out of 5

Rust for Rustaceans: Idiomatic Programming for Experienced Developers

4
The Rust Programming Language, 2nd Edition

Rating is 4.7 out of 5

The Rust Programming Language, 2nd Edition

5
Rust Atomics and Locks: Low-Level Concurrency in Practice

Rating is 4.6 out of 5

Rust Atomics and Locks: Low-Level Concurrency in Practice

6
Zero To Production In Rust: An introduction to backend development

Rating is 4.5 out of 5

Zero To Production In Rust: An introduction to backend development

7
Rust in Action

Rating is 4.4 out of 5

Rust in Action


How can I pattern match on function return values in Rust?

In Rust, pattern matching can be used to extract and handle different cases of function return values. You can use the match expression to pattern match on the returned value and handle each possibility separately.


Here's an example that demonstrates how to pattern match on function return values in Rust:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
fn divide_divisible(a: i32, b: i32) -> Result<i32, &'static str> {
    if b == 0 {
        return Err("Cannot divide by zero");
    }

    Ok(a / b)
}

fn main() {
    let result = divide_divisible(10, 2);

    match result {
        Ok(value) => println!("Result: {}", value),
        Err(error) => println!("Error: {}", error),
    }
}


In this example, the divide_divisible function divides two integers and returns a Result type that represents either a successful division (Ok) or an error message (Err). The match expression in the main function allows pattern matching on result.


If the result is Ok, the inner value can be extracted and printed accordingly. If the result is Err, the error message can be extracted and printed.


This way, you can handle different cases of return values using pattern matching in Rust.


What is the purpose of the @ operator in pattern matching?

The purpose of the "@" operator in pattern matching is to bind a pattern to a value and at the same time destructure the value to access its components. It allows you to use a pattern with a variable name to bind a value to that variable, as well as break down the structure of the value.


For example, in functional programming languages like F# or Haskell, you can use the "@" operator to match a list or a tuple and bind its components to variables. Here's a simple example in F#:

1
2
3
4
5
let printFirstAndLast list =
    match list with
    | [] -> ()
    | [x] -> printfn "Only one element: %A" x
    | first :: rest :: @last -> printfn "First: %A, Last: %A" first last


In this example, the pattern [first :: rest :: @last] matches a list with at least two elements, and binds the first element to first, the rest of the list to rest, and the last element to last. This allows you to access and work with these components within the body of the match case.


The "@" operator provides a convenient way to simultaneously bind a value to a variable and destructure it for further processing, thus enhancing the expressive power of pattern matching.


How can I match specific values in Rust?

To match specific values in Rust, you can use the match expression. Here is an example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
fn main() {
    let value = 5;

    match value {
        1 => println!("Value is 1"),
        2 => println!("Value is 2"),
        3 | 4 => println!("Value is 3 or 4"),
        5..=10 => println!("Value is between 5 and 10"),
        _ => println!("Value is something else"),
    }
}


In this example, the match expression compares the value against several patterns. If the value matches a pattern, the corresponding branch is executed. Here is what each pattern does:

  • 1 matches if the value is exactly 1.
  • 2 matches if the value is exactly 2.
  • 3 | 4 matches if the value is either 3 or 4.
  • 5..=10 matches if the value is between 5 and 10 (inclusive).
  • _ is a wildcard pattern that matches any value. It acts as a catch-all for values that don't match any other pattern.


You can replace the println! statements with any other code to perform the desired actions based on the matched values.

Twitter LinkedIn Telegram Whatsapp

Related Posts:

When working with Rust, there are multiple ways to interact with existing C code. One common approach is by using Rust&#39;s Foreign Function Interface (FFI) capabilities. FFI allows you to call C functions from Rust and vice versa. Here&#39;s a brief explanat...
Ownership and borrowing are two fundamental concepts in the Rust programming language that help ensure memory safety and prevent data races. Rust uses a unique ownership model that gives it a significant advantage over other languages.Ownership: Ownership is a...
To create a new Rust project, you can follow these steps:Open your preferred terminal or command prompt. Navigate to the directory where you want to create your Rust project. Run the following command to create a new Rust project structure: cargo new project_n...