4.5 if let 与 while let

虽然 match 表达式功能强大且安全,但在某些场景下,我们只关心枚举的某一个变体,而对其他情况采取统一或忽略的处理方式。此时,使用完整的 match 会显得冗长。Rust 提供了 if letwhile let 语法糖,用于简化这类单分支的模式匹配。

if let:简洁地处理单个模式

if let 允许你以类似 if 语句的形式解构一个值,仅当其匹配特定模式时执行代码块。

例如,假设有一个 Option<i32>,我们只关心 Some 的情况:

let some_value = Some(5);

if let Some(x) = some_value {
    println!("Got a value: {}", x);
}
// 如果是 None,则什么也不做

这等价于以下 match 写法,但更简洁:

match some_value {
    Some(x) => println!("Got a value: {}", x),
    None => (),
}

if let 也可以搭配 else 使用:

let status = Some("Success");

if let Some(s) = status {
    println!("Status: {}", s);
} else {
    println!("No status available");
}

这种写法在处理 Result 或自定义枚举时同样适用:

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

let msg = Message::Write(String::from("hello"));

if let Message::Write(text) = msg {
    println!("Writing message: {}", text);
}

while let:循环匹配直到不匹配为止

while let 在值持续匹配某个模式时重复执行循环体,常用于迭代器或栈/队列结构中。

一个典型用例是从 Vec 中逐个弹出元素(pop 返回 Option<T>):

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

while let Some(top) = stack.pop() {
    println!("Popped: {}", top);
}
// 输出:3, 2, 1

只要 stack.pop() 返回 Some,循环就继续;一旦返回 None(栈空),循环终止。

另一个例子是处理可选链或状态机中的连续有效状态。

注意事项

  • if letwhile let 虽然简洁,但会放弃穷尽性检查。编译器不会强制你处理所有可能的变体,因此应确保逻辑正确。
  • 它们适用于“只关心一种情况”的场景;如果需要处理多个变体,仍应使用 match 以保证清晰性和安全性。

小结

if letwhile let 是对 match 的有益补充,它们在保持 Rust 模式匹配优势的同时,减少了样板代码,提升了可读性。合理使用这些语法糖,可以让代码在简洁与安全之间取得良好平衡,尤其适合处理 OptionResult 或特定枚举变体的常见场景。

#Rust 入门教程 分享于 1 周前

内容由 AI 创作和分享,仅供参考