rust的模式匹配的完整用法
一、if let
表达式
用途:简化单分支模式匹配,处理特定模式并忽略其他情况。
基本语法
if let Pattern = Expression {
// 匹配成功时的逻辑
} else {
// 匹配失败时的逻辑(可选)
}
示例
let opt = Some(42);
// 只处理 Some 情况
if let Some(x) = opt {
println!("值为: {}", x); // 输出: 值为: 42
}
// 处理 Some 和 None
if let Some(50) = opt {
println!("匹配到50");
} else {
println!("未匹配到50"); // 输出: 未匹配到50
}
结合枚举和守卫
enum Message {
Text(String),
Number(i32),
}
let msg = Message::Number(7);
if let Message::Number(n) = msg && n % 2 == 0 {
println!("偶数: {}", n);
} else {
println!("奇数或无数字"); // 输出: 奇数或无数字
}
二、while let
表达式
用途:循环处理持续匹配某个模式的值,直到不匹配为止。
基本语法
while let Pattern = Expression {
// 循环体逻辑
}
示例
let mut stack = vec![1, 2, 3];
// 持续弹出元素直到栈空
while let Some(top) = stack.pop() {
println!("弹出: {}", top); // 依次输出3, 2, 1
}
处理复杂模式
let mut data = vec![Some(4), None, Some(6)];
// 仅处理 Some 值且大于5的情况
while let Some(Some(x)) = data.pop() && x > 5 {
println!("处理 {}", x); // 输出: 处理6
}
三、嵌套模式匹配
用途:解构嵌套的数据结构(如元组、枚举、结构体等)。
示例
enum Color {
Rgb(u8, u8, u8),
Hsv(u8, u8, u8),
}
let color = Color::Rgb(255, 0, 128);
match color {
Color::Rgb(r, g, b) if g == 0 => {
println!("纯红色,蓝色分量: {}", b); // 输出: 纯红色,蓝色分量: 128
}
_ => println!("其他颜色"),
}
嵌套解构Option
let nested = Some(Some(10));
match nested {
Some(Some(inner)) => println!("内部值: {}", inner), // 输出: 内部值: 10
Some(None) => println!("内部为None"),
None => println!("外层为None"),
}
四、@
绑定
用途:在匹配模式的同时将值绑定到变量,便于后续使用。
基本语法
Pattern @ SubPattern
示例
范围匹配:
let age = 25;
match age {
a @ 0..=17 => println!("未成年,年龄: {}", a),
a @ 18..=120 => println!("成年,年龄: {}", a), // 输出: 成年,年龄: 25
_ => unreachable!(),
}
结构体字段绑定:
struct Point { x: i32, y: i32 }
let p = Point { x: 5, y: 20 };
match p {
Point { x: x_val @ 0..=10, y: y_val @ 15..=25 } => {
println!("x在0-10: {}, y在15-25: {}", x_val, y_val); // 输出匹配
}
_ => (),
}
枚举值绑定:
enum Result<T> {
Ok(T),
Err(String),
}
let result = Result::Ok(42);
match result {
Result::Ok(num @ 0..=100) => println!("有效值: {}", num), // 输出: 有效值: 42
Result::Ok(num) => println!("超出范围的值: {}", num),
Result::Err(e) => println!("错误: {}", e),
}
五、组合使用技巧
-
if let
与@
绑定:if let Some(x @ 1..=5) = Some(3) { println!("匹配到1-5的值: {}", x); // 输出: 3 }
-
嵌套
if let
:let triple = Some(Some(Some(7))); if let Some(Some(Some(n))) = triple { println!("深度嵌套的值: {}", n); // 输出: 7 }
-
while let
与复杂模式:let mut data = vec![Some(5), None, Some(8)]; while let Some(Some(x @ 5..=10)) = data.pop() { println!("处理有效值: {}", x); // 输出: 8, 5 }
六、注意事项
-
所有权问题:模式匹配可能触发移动,使用
ref
或ref mut
避免:let name = Some(String::from("Rust")); if let Some(ref s) = name { println!("借用的值: {}", s); // 不会移动所有权 }
-
穷尽性检查:
match
必须处理所有可能分支,而if let
和while let
仅处理指定模式。