if let

Para alguns casos de uso, quando correspondemos enumerações, match é difícil. Por exemplo:

#![allow(unused)] fn main() { // Tornar `optional` do tipo `Option<i32>` let optional = Some(7); match optional { Some(i) => { println!("This is a really long string and `{:?}`", i); // ^ Precisava de 2 indentações só assim poderíamos // desestruturar `i` a partir da opção. }, _ => {}, // ^ Obrigatório porque `match` é exaustiva. // Não parece como espaço desperdiçado? }; }

if let é mais clara para este caso de uso e além disso permite várias opções de fracasso a serem especificadas:

fn main() {
// Todos têm o tipo `Option<i32>`
let number = Some(7);
let letter: Option<i32> = None;
let emoticon: Option<i32> = None;
// A construção `if let` lê-se: "se `let` desestruturar `number` na"
// `Some(i)`, avaliar o bloco (`{}`).
if let Some(i) = number {
println!("Matched {:?}!", i);
}
// Se precisarmos de especificar uma falha, usamos uma `else`:
if let Some(i) = letter {
println!("Matched {:?}!", i);
} else {
// Desestruturação falhada. Mudar para o caso de falha.
println!("Didn't match a number. Let's go with a letter!");
}
// Fornecer uma condição de falha alterada.
let i_like_letters = false;
if let Some(i) = emoticon {
println!("Matched {:?}!", i);
// Desestruturação falhada. Avaliar uma condição `else if` para
// ver se o ramo de falha alternada deveria ser considerado:
} else if i_like_letters {
println!("Didn't match a number. Let's go with a letter!");
} else {
// A condição avaliou `false`. Este ramo é o padrão:
println!("I don't like letters. Let's go with an emoticon :)!");
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

De algum modo, if let pode ser usada para corresponder apenas o valor de enumeração:

// Nossa enumeração de exemplo
enum Foo {
Bar,
Baz,
Qux(u32)
}
fn main() {
// Criar variáveis de exemplo
let a = Foo::Bar;
let b = Foo::Baz;
let c = Foo::Qux(100);
// Variável `a` corresponde `Foo::Bar`
if let Foo::Bar = a {
println!("a is foobar");
}
// Variável `b` não corresponde `Foo::Bar`
// Então isto não imprimirá nada
if let Foo::Bar = b {
println!("b is foobar");
}
// Variável `c` corresponde `Foo::Qux` que tem um valor
// Semelhante à `Some()` no exemplo anterior
if let Foo::Qux(value) = c {
println!("c is {}", value);
}
// Vínculos também funcionam com `if let`
if let Foo::Qux(value @ 100) = c {
println!("c is one hundred");
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Um outro beneficio é que if let permite-nos corresponder variantes de enumeração não parametrizadas. Isto é verdadeiro mesmo em casos onde a enumeração não implementa ou deriva PartialEq. Em tais casos if Foo::Bar == a falharia ao compilar, porque as instâncias da enumeração não podem ser equiparadas, no entanto if let continuará a funcionar.

Gostarias dum desafio? Corrija o seguinte exemplo para usar if let:

// Esta enumeração propositadamente não implemente nem deriva `PartialEq`.
// É por isto que a comparação abaixo `Foo::Bar == a` falha.
enum Foo {Bar}
fn main() {
let a = Foo::Bar;
// Variável `a` corresponde `Foo::Bar`
if Foo::Bar == a {
// ^-- isto causa um erro de tempo de compilação. Use `if let`.
println!("a is foobar");
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Consulte também:

enum, Option, e o RFC