模式匹配
模式和匹配是两个不同的概念。
在 Rust 中,模式匹配最常用的就是 match(要求穷尽所有可能性) 和 if let(满足单一可能性)。
作用是
- 减少分支代码造成的嵌套循环
- 方便解构复杂类型
模式的组成
- 字面值(Literals):例如数字或字符串
- 解构数据结构:数组、枚举、结构体、元组等
- 变量 (Variables):命名的变量
- 通配符 (Wildcards):
_表示任意值 - 占位符(Placeholders):尚未具体定义的部分
使用位置
- 比较模式和值,匹配成功则提取并使用数据
- 一般作为match表达式的内部分支。
以下是模式使用的位置:
match表达式必须穷尽所有可能性
分支使用
PATTERN => EXPRESSION形式示例:
rustmatch x { Some(i) => Some(i + 1), None => None, }
if let表达式用于只关心一种匹配情况的简写
可搭配
else if和else if let使用示例:
rustif let Some(color) = favorite_color { println!("Using {color} as background"); } else if is_tuesday { println!("Tuesday is green day!"); }
while let条件循环只要模式匹配就一直循环
示例:
rustwhile let Ok(msg) = rx.recv() { println!("Got: {}", msg); }
for循环循环变量本身就是模式
可用于解构:
rustfor (index, value) in v.iter().enumerate() { println!("{} is at index {}", value, index); }
let语句所有
let绑定都是模式匹配示例:
rustlet (x, y, z) = (1, 2, 3); // 解构元组
函数参数
参数也是模式
示例:
rustfn print_coordinates(&(x, y): &(i32, i32)) { println!("Current location: ({}, {})", x, y); }
语法
匹配字面值
rustlet x = 1; match x { 1 => println!("one"), 2 => println!("two"), _ => println!("other"), }匹配命名变量
注意变量遮蔽问题
示例:
rustmatch Some(5) { Some(y) => println!("Matched, y = {}", y), // 新建变量 y _ => (), }
多模式匹配
- 使用
|表示"或"
rustmatch x { 1 | 2 => println!("one or two"), _ => println!("other"), }- 使用
范围匹配
- 使用
..=匹配闭区间
rustmatch x { 1..=5 => println!("one through five"), _ => println!("other"), }- 使用
解构
结构体:
rustlet p = Point { x: 0, y: 7 }; let Point { x, y } = p;枚举:
rustmatch msg { Message::Quit => println!("Quit"), Message::Move { x, y } => println!("Move to {}, {}", x, y), }嵌套结构:
rustmatch msg { Message::ChangeColor(Color::Rgb(r, g, b)) => println!("RGB"), _ => (), }
忽略值
- 使用
_忽略整个值 - 使用
_var忽略未使用变量(避免警告) - 使用
..忽略剩余部分
rustlet (x, ..) = (1, 2, 3); // 只绑定x,忽略其余- 使用
匹配守卫
- 额外的
if条件
rustmatch num { Some(x) if x % 2 == 0 => println!("Even"), Some(x) => println!("Odd"), None => (), }- 额外的
@绑定- 绑定值到变量同时测试
rustmatch msg { Message::Hello { id: id_variable @ 3..=7 } => { println!("Found id in range: {}", id_variable) } _ => (), }
可反驳性(Refutability)
不可反驳模式(Irrefutable)
- 总能匹配成功的模式
- 用于:
let语句、函数参数、for循环 - 示例:
let x = 5;
可反驳模式(Refutable)
- 可能匹配失败的模式
- 用于:
match分支(除最后一个)、if let、while let - 示例:
if let Some(x) = value
错误处理
- 在需要不可反驳模式的地方使用可反驳模式会报错
- 修复方法:改用
if let等接受可反驳模式的语法