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);

4. // Repeatedly try this test.
5. loop {
6. match optional {
7. // If `optional` destructures, evaluate the block.
8. Some(i) => {
9. if i > 9 {
10. println!("Greater than 9, quit!");
11. optional = None;
12. } else {
13. println!("`i` is `{:?}`. Try again.", i);
14. optional = Some(i + 1);
15. }
16. // ^ Requires 3 indentations!
17. },
18. // Quit the loop when the destructure fails:
19. _ => { break; }
20. // ^ Why should this be required? There must be a better way!
21. }
22. }

Using while let makes this sequence much nicer:

1. fn main() {
2. // Make `optional` of type `Option<i32>`
3. let mut optional = Some(0);

5. // This reads: "while `let` destructures `optional` into
6. // `Some(i)`, evaluate the block (`{}`). Else `break`.
7. while let Some(i) = optional {
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. // ^ Less rightward drift and doesn't require
16. // explicitly handling the failing case.
17. }
18. // ^ `if let` had additional optional `else`/`else if`
19. // clauses. `while let` does not have these.
20. }

See also:

enum, Option, and the RFC