Rust by Example - страница 22

стр.

>

>Some(n @ 42) => println!("The Answer: {}!", n),

>// Match any other number.

>Some(n) => println!("Not interesting... {}", n),

>// Match anything else (`None` variant).

>_ => (),

>}

>}

>הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

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


>#![allow(unused)]

>fn main() {

>// Make `optional` of type `Option`

>let optional = Some(7);


>match optional {

>Some(i) => {

>println!("This is a really long string and `{:?}`", i);

>// ^ Needed 2 indentations just so we could destructure

>// `i` from the option.

>},

>_ => {},

>// ^ Required because `match` is exhaustive. Doesn't it seem

>// like wasted space?

>};


>}

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

>fn main() {

>// All have type `Option`

>let number = Some(7);

>let letter: Option = None;

>let emoticon: Option = None;

>// The `if let` construct reads: "if `let` destructures `number` into

>// `Some(i)`, evaluate the block (`{}`).

>if let Some(i) = number {

>println!("Matched {:?}!", i);

>}

>// If you need to specify a failure, use an else:

>if let Some(i) = letter {

>println!("Matched {:?}!", i);

>} else {

>// Destructure failed. Change to the failure case.

>println!("Didn't match a number. Let's go with a letter!");

>}

>// Provide an altered failing condition.

>let i_like_letters = false;

>if let Some(i) = emoticon {

>println!("Matched {:?}!", i);

>// Destructure failed. Evaluate an `else if` condition to see if the

>// alternate failure branch should be taken:

>} else if i_like_letters {

>println!("Didn't match a number. Let's go with a letter!");

>} else {

>// The condition evaluated false. This branch is the default:

>println!("I don't like letters. Let's go with an emoticon :)!");

>}

>}

>הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

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

>// Our example enum

>enum Foo {

>Bar,

>Baz,

>Qux(u32)

>}

>fn main() {

>// Create example variables

>let a = Foo::Bar;

>let b = Foo::Baz;

>let c = Foo::Qux(100);

>// Variable a matches Foo::Bar

>if let Foo::Bar = a {

>println!("a is foobar");

>}

>// Variable b does not match Foo::Bar

>// So this will print nothing

>if let Foo::Bar = b {

>println!("b is foobar");

>}

>// Variable c matches Foo::Qux which has a value

>// Similar to Some() in the previous example

>if let Foo::Qux(value) = c {

>println!("c is {}", value);

>}

>// Binding also works with `if let`

>if let Foo::Qux(value @ 100) = c {

>println!("c is one hundred");

>}

>}

>הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Another benefit is that if let allows us to match non-parameterized enum variants. This is true even in cases where the enum doesn't implement or derive PartialEq. In such cases if Foo::Bar == a would fail to compile, because instances of the enum cannot be equated, however if let will continue to work.