if let

For some use cases, when matching enums, match is awkward. For example:

  1. // Make `optional` of type `Option<i32>`
  2. let optional = Some(7);
  3. match optional {
  4. Some(i) => {
  5. println!("This is a really long string and `{:?}`", i);
  6. // ^ Needed 2 indentations just so we could destructure
  7. // `i` from the option.
  8. },
  9. _ => {},
  10. // ^ Required because `match` is exhaustive. Doesn't it seem
  11. // like wasted space?
  12. };

if let is cleaner for this use case and in addition allows various
failure options to be specified:

  1. fn main() {
  2. // All have type `Option<i32>`
  3. let number = Some(7);
  4. let letter: Option<i32> = None;
  5. let emoticon: Option<i32> = None;
  6. // The `if let` construct reads: "if `let` destructures `number` into
  7. // `Some(i)`, evaluate the block (`{}`).
  8. if let Some(i) = number {
  9. println!("Matched {:?}!", i);
  10. }
  11. // If you need to specify a failure, use an else:
  12. if let Some(i) = letter {
  13. println!("Matched {:?}!", i);
  14. } else {
  15. // Destructure failed. Change to the failure case.
  16. println!("Didn't match a number. Let's go with a letter!");
  17. };
  18. // Provide an altered failing condition.
  19. let i_like_letters = false;
  20. if let Some(i) = emoticon {
  21. println!("Matched {:?}!", i);
  22. // Destructure failed. Evaluate an `else if` condition to see if the
  23. // alternate failure branch should be taken:
  24. } else if i_like_letters {
  25. println!("Didn't match a number. Let's go with a letter!");
  26. } else {
  27. // The condition evaluated false. This branch is the default:
  28. println!("I don't like letters. Let's go with an emoticon :)!");
  29. };
  30. }

In the same way, if let can be used to match any enum value:

  1. // Our example enum
  2. enum Foo {
  3. Bar,
  4. Baz,
  5. Qux(u32)
  6. }
  7. fn main() {
  8. // Create example variables
  9. let a = Foo::Bar;
  10. let b = Foo::Baz;
  11. let c = Foo::Qux(100);
  12. // Variable a matches Foo::Bar
  13. if let Foo::Bar = a {
  14. println!("a is foobar");
  15. }
  16. // Variable b does not match Foo::Bar
  17. // So this will print nothing
  18. if let Foo::Bar = b {
  19. println!("b is foobar");
  20. }
  21. // Variable c matches Foo::Qux which has a value
  22. // Similar to Some() in the previous example
  23. if let Foo::Qux(value) = c {
  24. println!("c is {}", value);
  25. }
  26. }

See also:

enum, Option, and the RFC