while let

if let 类似,while let 也可以把别扭的 match 改写得好看一些。考虑下面这 段使 i 不断增加的代码:

  1. // 将 `optional` 设为 `Option<i32>` 类型
  2. let mut optional = Some(0);
  3. // 重复运行这个测试。
  4. loop {
  5. match optional {
  6. // 如果 `optional` 解构成功,就执行下面语句块。
  7. Some(i) => {
  8. if i > 9 {
  9. println!("Greater than 9, quit!");
  10. optional = None;
  11. } else {
  12. println!("`i` is `{:?}`. Try again.", i);
  13. optional = Some(i + 1);
  14. }
  15. // ^ 需要三层缩进!
  16. },
  17. // 当解构失败时退出循环:
  18. _ => { break; }
  19. // ^ 为什么必须写这样的语句呢?肯定有更优雅的处理方式!
  20. }
  21. }

使用 while let 可以使这段代码变得更加优雅:

  1. fn main() {
  2. // 将 `optional` 设为 `Option<i32>` 类型
  3. let mut optional = Some(0);
  4. // 这读作:当 `let` 将 `optional` 解构成 `Some(i)` 时,就
  5. // 执行语句块(`{}`)。否则就 `break`。
  6. while let Some(i) = optional {
  7. if i > 9 {
  8. println!("Greater than 9, quit!");
  9. optional = None;
  10. } else {
  11. println!("`i` is `{:?}`. Try again.", i);
  12. optional = Some(i + 1);
  13. }
  14. // ^ 使用的缩进更少,并且不用显式地处理失败情况。
  15. }
  16. // ^ `if let` 有可选的 `else`/`else if` 分句,
  17. // 而 `while let` 没有。
  18. }

参见:

枚举Option,和相关的 RFC