DAILY DOCDAILY DOC
Rust
Node
Notes
Ubuntu
Leetcode
  • it-tools
  • excalidraw
  • linux-command
Rust
Node
Notes
Ubuntu
Leetcode
  • it-tools
  • excalidraw
  • linux-command
  • rust

    • Rust
    • add
    • 属性(attributes)
    • cargo issue
    • cli
    • build.rs
    • Enums
    • eventEmitter(rust)
    • 格式化输出 std::fmt
    • rust iterator
    • rust 学习计划
    • 生命周期(lifetime)
    • Linked List
    • log
    • macros
    • mem::size_of
    • niche optimization
    • Rust 所有权
    • 模式匹配(pattern matching)
    • module system
    • result & option
    • .rust-analyzer.json
    • rust startup
    • rust-test
    • 可见性(visibility)
    • cargo
    • toml

模式匹配(pattern matching)

1. match 表达式

match表达式是Rust中最常用的模式匹配工具,用于将一个值与多个模式进行比较,并执行相应的代码块。

fn main() {
    let number = 7;

    match number {
        1 => println!("One!"),
        2 | 3 | 5 | 7 | 11 => println!("This is a prime"),
        13..=19 => println!("A teen number"),
        _ => println!("Some other number"),
    }
}

1.1 模式匹配基础

  • 单值匹配:匹配具体的单个值,如1。
  • 多值匹配:使用|匹配多个值,如2 | 3 | 5 | 7 | 11。
  • 范围匹配:使用..=匹配一个范围内的值,如13..=19。
  • 通配符模式:使用_匹配所有其他值。

2. 解构结构体、枚举和元组

模式匹配可以用于解构复杂的数据结构,如结构体、枚举和元组。

2.1 解构元组

fn main() {
    let pair = (0, -2);

    match pair {
        (0, y) => println!("First is zero and y is {}", y),
        (x, 0) => println!("x is {} and second is zero", x),
        _ => println!("It is a pair of other values"),
    }
}

2.2 解构枚举

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

fn main() {
    let msg = Message::ChangeColor(0, 160, 255);

    match msg {
        Message::Quit => println!("The Quit variant has no data to destructure."),
        Message::Move { x, y } => println!("Move in the x direction {} and in the y direction {}", x, y),
        Message::Write(text) => println!("Text message: {}", text),
        Message::ChangeColor(r, g, b) => println!("Change the color to red {}, green {}, and blue {}", r, g, b),
    }
}

2.3 解构结构体

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

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

    match p {
        Point { x, y: 0 } => println!("On the x axis at {}", x),
        Point { x: 0, y } => println!("On the y axis at {}", y),
        Point { x, y } => println!("On neither axis: ({}, {})", x, y),
    }
}

3. if let 和 while let

if let 和 while let 提供了一种简洁的方式,只在匹配一个模式时执行代码。

3.1 if let 表达式

let some_value = Some(5);

if let Some(x) = some_value {
    println!("Matched! x = {}", x);
}

3.2 while let 表达式

let mut stack = vec![1, 2, 3];

while let Some(top) = stack.pop() {
    println!("{}", top);
}

4. 函数参数模式匹配

在函数参数中也可以使用模式匹配,以解构传入的参数。

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

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

fn main() {
    let point = Point { x: 3, y: 5 };
    print_coordinates(&point);
}

5. 绑定和守卫

5.1 绑定

在模式中使用@符号可以绑定部分模式到变量。

enum Message {
    Hello { id: i32 },
}

fn main() {
    let msg = Message::Hello { id: 5 };

    match msg {
        Message::Hello { id: id_variable @ 3..=7 } => {
            println!("Found an id in range: {}", id_variable)
        }
        Message::Hello { id: 10..=12 } => {
            println!("Found an id in another range")
        }
        Message::Hello { id } => {
            println!("Found some other id: {}", id)
        }
    }
}

5.2 守卫

模式守卫是附加在匹配条件上的额外if条件。

let num = Some(4);

match num {
    Some(x) if x < 5 => println!("Less than five: {}", x),
    Some(x) => println!("{}", x),
    None => (),
}

6. 使用 _ 忽略值

在模式匹配中,可以使用 _ 忽略某些值或模式。

fn main() {
    let tuple = (1, 2, 3, 4, 5);

    match tuple {
        (first, _, third, _, fifth) => {
            println!("Values are: {}, {}, {}", first, third, fifth);
        }
    }
}

7. 使用 ref 和 ref mut

在模式中使用ref和ref mut来获得值的引用而不是值本身。

fn main() {
    let mut robot_name = Some(String::from("Bors"));

    match robot_name {
        Some(ref mut name) => *name = String::from("Bors-2.0"),
        None => (),
    }

    println!("robot_name: {:?}", robot_name);
}

8. 复杂模式匹配示例

为了更好地理解Rust中的模式匹配,这里展示一些复杂的示例,包括嵌套模式和组合模式。

8.1 嵌套模式

嵌套模式允许你匹配更深层次的数据结构。这在处理复杂的枚举类型时非常有用。

enum Color {
    Red,
    Blue,
    Green,
}

enum Vehicle {
    Car { color: Color, model: String },
    Bike { color: Color, gears: u8 },
}

fn main() {
    let my_vehicle = Vehicle::Car { 
        color: Color::Red, 
        model: String::from("Tesla Model S")
    };

    match my_vehicle {
        Vehicle::Car { color: Color::Red, model } => {
            println!("It's a red car, model: {}", model);
        }
        Vehicle::Car { color, model } => {
            println!("It's a {:?} car, model: {}", color, model);
        }
        Vehicle::Bike { color, gears } => {
            println!("It's a {:?} bike with {} gears", color, gears);
        }
    }
}

在这个示例中,我们定义了两个枚举Color和Vehicle,并在match表达式中使用嵌套模式来匹配车辆的颜色和类型。

8.2 组合模式

组合模式允许你在一个匹配分支中使用多个模式。

fn main() {
    let x = 5;

    match x {
        1 | 2 |3..=7 => println!("One or two or three to seven"),
        _ => println!("Anything else"),
    }
}

在这个示例中,我们在同一个匹配分支中使用了多个模式(1 | 2)和范围模式(3..=7)。

9. 更多模式匹配特性

9.1 使用 @ 绑定值

使用@符号,你可以在模式中绑定值,同时解构它们。

enum Message {
    Hello { id: i32 },
}

fn main() {
    let msg = Message::Hello { id: 5 };

    match msg {
        Message::Hello { id: id_variable @ 3..=7 } => {
            println!("Found an id in range: {}", id_variable)
        }
        Message::Hello { id } => {
            println!("Found some other id: {}", id)
        }
    }
}

在这个示例中,id_variable @ 3..=7模式不仅匹配范围3..=7内的值,还将匹配的值绑定到id_variable变量。

9.2 使用 _ 忽略未使用的值

使用_符号可以忽略匹配时不需要的值。

fn main() {
    let (a, _, c) = (1, 2, 3);
    println!("a: {}, c: {}", a, c);
}

在这个示例中,我们忽略了元组中的第二个值2。

10. 高级模式匹配

10.1 高级守卫模式

模式守卫可以使用逻辑运算符来实现更复杂的条件。

fn main() {
    let num = Some(4);

    match num {
        Some(x) if x % 2 == 0 && x > 2 => println!("Matched even number greater than 2: {}", x),
        Some(x) => println!("Other number: {}", x),
        None => (),
    }
}

在这个示例中,模式守卫if x % 2 == 0 && x > 2同时检查两个条件。

10.2 使用 ref 和 ref mut 获得引用

在模式中使用ref和ref mut可以获取值的引用而不是值本身。

fn main() {
    let name = Some(String::from("Alice"));

    match name {
        Some(ref n) => println!("Found a name: {}", n),
        None => println!("No name found"),
    }
}

在这个示例中,Some(ref n)模式获取String的引用而不是所有权。

Last Updated:
Contributors: rosendo
Prev
Rust 所有权
Next
module system