Rust中模式匹配

模式匹配(Pattern Matching) 是一种强大的控制流工具,主要用于解构数据结构、匹配值和控制程序分支。常见匹配结构有:

  • match 表达式
  • if let
  • while let
  • for 循环
  • 函数参数解构

match

match是模式匹配的核心:

  • 穷尽性检查:编译器强制要求处理所有可能情况。
  • 模式顺序:按顺序匹配,首个匹配成功即执行对应分支。
    • _ 匹配任何值,用于忽略不需要的值;
    • .. 忽略结构体 / 元组的部分字段;
    • |(管道符)实现或逻辑匹配,同时匹配多个;
    • @绑定,将匹配值绑定到变量;
  • 返回值:每个分支的表达式结果必须是相同类型。
rust 复制代码
match value {
    pattern1 => expr1,
    pattern2 => expr2,
    _ => default_expr,
}

字面量模式

直接匹配具体的值(字面量),支持数字、字符串、布尔值等。

rust 复制代码
let x = 3;
match x {
    1 => println!("One"),
    z @ (2 | 3) => println!("or-{}", z),   // 多重匹配
    z @ 4..=6 => println!("rang-{}", z), 	// 范围匹配
    _ => println!("Other"),	// 默认匹配
}

守卫模式

在模式后添加 if 条件,进一步过滤匹配(仅当模式匹配且条件为真时生效)。

rust 复制代码
let num = 8;

match num {
    n if n % 2 == 0 => println!("Even: {}", n), // 8是偶数,匹配成功
    n => println!("Odd: {}", n),
}

let pair = (2, 3);
match pair {
    (x, y) if x + y == 5 => println!("Sum is 5"), // 2+3=5,匹配成功
    _ => println!("Sum is not 5"),
}

引用模式

当模式中的值是引用类型时,需要注意 refref mut(否则会产生移动语义,原有变量的所有权会丢失):

rust 复制代码
let tmp = &Some(10); // 临时值的引用

match tmp {
    // Some(x) => println!("x = {}", x),  	// x为&i32
    &Some(x) => println!("x = {}", x),		// x为i32
    _ => {}
}

所有权与引用

rust 复制代码
// 引用类型
let rOne = Some(String::from("hello"));
match rOne {
    Some(ref x) => println!("x = {}", x), 
    _ => {}
}
println!("rOne: {:?}", rOne);

// 所有权移动
let rTwo = Some(String::from("hello"));
match rTwo {
    Some(x) => println!("x = {}", x), 
    _ => {}
}
// 此时rTwo已没有所有权,不能再打印
// println!("rOne: {:?}", rTwo);

可修改引用,对原值进行修改

rust 复制代码
let mut a = Some(1);
match a {
    Some(ref mut v) => *v += 10,
    None => (),
}

println!("a = {:?}", a); // 输出 Some(11)

绑定

可以在匹配时绑定部分匹配值:

rust 复制代码
enum Message { Hello { id: i32 } }

let msg = Message::Hello { id: 7 };

match msg {
    Message::Hello { id: id_variable @ 3..=10 } => {
        println!("id 在范围内: {}", id_variable);
    }
    Message::Hello { id } => {
        println!("id 不在范围: {}", id);
    }
}

复合结构匹配

结构体模式

可自动解构结构中的字段,

rust 复制代码
struct Point { x: i32, y: i32 }

let p = Point { x: 10, y: 20 };
match p {
    Point { x: 0, y } => println!("On y-axis at {}", y),
    Point { x, y: 0 } => println!("On x-axis at {}", x),
    Point { x, y } => println!("({}, {})", x, y),
    // Point { x, .. } => println!("({}, -)", x), //不关心y
}

枚举模式

枚举是模式匹配的核心应用场景,用于匹配不同的枚举变体(Variant)。

rust 复制代码
enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

let msg = Message::Move { x: 5, y: 10 };
match msg {
    Message::Quit => println!("Quit"),
    // 解构结构体变体的字段
    Message::Move { x, y } => println!("Move to ({}, {})", x, y), // 匹配成功
    // 解构单值变体
    Message::Write(s) => println!("Write: {}", s),
    // 解构元组变体
    Message::ChangeColor(r, g, b) => println!("Color: ({}, {}, {})", r, g, b),
}

切片模式

匹配切片或数组的结构(长度固定时可精确匹配,长度不固定时用 .. 匹配任意长度)。

rust 复制代码
let arr = [1, 2, 3, 4];

// 匹配长度为4的数组,且首元素为1,末元素为4
match arr {
    [1, a, b, 4] => println!("a={}, b={}", a, b), // a=2, b=3
    _ => println!("Other"),
}

let slice = &[10, 20, 30];

// 匹配切片的开头和结尾,中间用 .. 匹配任意长度
match slice {
    [first, .., last] => println!("First: {}, Last: {}", first, last), // First:10, Last:30
    [] => println!("Empty slice"),
}

其他模式匹配

if let

当只需要处理一种匹配情况,其他情况忽略时使用

rust 复制代码
let option = Some(5);

// 等价于 match option { Some(x) => ..., _ => () }
if let Some(x) = option {
    println!("Got: {}", x); // 输出 "Got: 5"
}

while let

当需要反复匹配某个模式,直到不匹配时退出循环。

rust 复制代码
let mut stack = vec![1, 2, 3];

// 每次弹出最后一个元素,直到栈为空
while let Some(top) = stack.pop() {
    println!("Popped: {}", top); // 依次输出 3、2、1
}

for循环

在循环中解构迭代器的元素

rust 复制代码
let pairs = vec![(1, "one"), (2, "two")];

// 解构元组 (数字, 字符串)
for (num, s) in pairs {
    println!("{}: {}", num, s); // 输出 "1: one"、"2: two"
}
相关推荐
编码浪子18 小时前
Dioxus hot-dog 总结
rust
光影少年1 天前
rust生态及学习路线,应用领域
开发语言·学习·rust
Kiri霧2 天前
Linux下的Rust 与 C 的互操作性解析
c语言·开发语言·rust
大鱼七成饱2 天前
Rust 多线程编程入门:从 thread::spawn 步入 Rust 并发世界
后端·rust
ServBay3 天前
Rust 1.89更新,有哪些值得关注的新功能
后端·rust
MOON404☾3 天前
Rust程序语言设计(5-8)
开发语言·后端·rust
Vallelonga4 天前
Rust 中的数组和数组切片引用
开发语言·rust
Kiri霧4 天前
Rust模式匹配详解
开发语言·windows·rust
mit6.8244 天前
理念导向编程|ts
rust·typescript