while let

Similar to if let, while let can make awkward match sequences
more tolerable. Consider the following sequence that increments i:

  1. // Make `optional` of type `Option<i32>`
  2. let mut optional = Some(0);
  3. // Repeatedly try this test.
  4. loop {
  5. match optional {
  6. // If `optional` destructures, evaluate the block.
  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. // ^ Requires 3 indentations!
  16. },
  17. // Quit the loop when the destructure fails:
  18. _ => { break; }
  19. // ^ Why should this be required? There must be a better way!
  20. }
  21. }

Using while let makes this sequence much nicer:

  1. fn main() {
  2. // Make `optional` of type `Option<i32>`
  3. let mut optional = Some(0);
  4. // This reads: "while `let` destructures `optional` into
  5. // `Some(i)`, evaluate the block (`{}`). Else `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. // ^ Less rightward drift and doesn't require
  15. // explicitly handling the failing case.
  16. }
  17. // ^ `if let` had additional optional `else`/`else if`
  18. // clauses. `while let` does not have these.
  19. }

See also:

enum, Option, and the RFC