if let

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.

Would you like a challenge? Fix the following example to use if let:

// This enum purposely neither implements nor derives PartialEq.

// That is why comparing Foo::Bar == a fails below.

enum Foo {Bar}

fn main() {

let a = Foo::Bar;

// Variable a matches Foo::Bar

if Foo::Bar == a {

// ^-- this causes a compile-time error. Use `if let` instead.

println!("a is foobar");

}

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

See also:

enum, Option, and the RFC

Загрузка...