Explorando a Construção if let do Rust

Beginner

This tutorial is from open-source community. Access the source code

Introdução

Neste laboratório, exploramos o uso da construção if let em Rust, que permite um código mais limpo ao corresponder a enumerações e fornece a capacidade de especificar opções de falha. Também demonstramos como if let pode ser usado para corresponder a qualquer valor de enumeração, incluindo variantes não parametrizadas. Além disso, fornecemos um exemplo de correção de código que tenta comparar dois valores de enumeração usando if let em vez disso.

Nota: Se o laboratório não especificar um nome de arquivo, você pode usar qualquer nome de arquivo que desejar. Por exemplo, você pode usar main.rs, compilar e executar com rustc main.rs && ./main.

if let

Para alguns casos de uso, ao corresponder a enumerações, match é pouco prático. Por exemplo:

// Crie `optional` do tipo `Option<i32>`
let optional = Some(7);

match optional {
    Some(i) => {
        println!("Esta é uma string longa e `{:?}`", i);
        // ^ Necessário 2 níveis de indentação apenas para desestruturar
        // `i` da opção.
    },
    _ => {},
    // ^ Necessário porque `match` é exaustivo. Não parece
    // espaço desperdiçado?
};

if let é mais limpo para este caso de uso e, além disso, permite especificar várias opções de falha:

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 `let` desestruturar `number` em
    // `Some(i)`, avalie o bloco (`{}`).
    if let Some(i) = number {
        println!("Correspondência {:?}!", i);
    }

    // Se precisar especificar uma falha, use um else:
    if let Some(i) = letter {
        println!("Correspondência {:?}!", i);
    } else {
        // Desestruturação falhou. Mude para o caso de falha.
        println!("Não correspondeu a um número. Vamos com uma letra!");
    }

    // Forneça uma condição de falha alterada.
    let i_like_letters = false;

    if let Some(i) = emoticon {
        println!("Correspondência {:?}!", i);
    // Desestruturação falhou. Avalie uma condição `else if` para ver se o
    // ramo alternativo de falha deve ser tomado:
    } else if i_like_letters {
        println!("Não correspondeu a um número. Vamos com uma letra!");
    } else {
        // A condição avaliou falso. Este ramo é o padrão:
        println!("Não gosto de letras. Vamos com um emoticon :)!");
    }
}

Da mesma forma, if let pode ser usado para corresponder a qualquer valor de enumeração:

// Nossa enumeração de exemplo
enum Foo {
    Bar,
    Baz,
    Qux(u32)
}

fn main() {
    // Crie variáveis de exemplo
    let a = Foo::Bar;
    let b = Foo::Baz;
    let c = Foo::Qux(100);

    // A variável a corresponde a Foo::Bar
    if let Foo::Bar = a {
        println!("a é foobar");
    }

    // A variável b não corresponde a Foo::Bar
    // Portanto, isso não imprimirá nada
    if let Foo::Bar = b {
        println!("b é foobar");
    }

    // A variável c corresponde a Foo::Qux que tem um valor
    // Similar a Some() no exemplo anterior
    if let Foo::Qux(value) = c {
        println!("c é {}", value);
    }

    // O vínculo também funciona com `if let`
    if let Foo::Qux(value @ 100) = c {
        println!("c é cem");
    }
}

Outro benefício é que if let permite corresponder a variantes de enumeração não parametrizadas. Isso é verdade mesmo em casos onde a enumeração não implementa ou deriva PartialEq. Nesses casos, if Foo::Bar == a falharia na compilação, porque as instâncias da enumeração não podem ser igualadas, no entanto, if let continuará funcionando.

Você gostaria de um desafio? Corrija o exemplo a seguir para usar if let:

// Esta enumeração propositalmente não implementa nem deriva PartialEq.
// É por isso que comparar Foo::Bar == a falha abaixo.
enum Foo {Bar}

fn main() {
    let a = Foo::Bar;

    // A variável a corresponde a Foo::Bar
    if Foo::Bar == a {
    // ^-- isso causa um erro de tempo de compilação. Use `if let` em vez disso.
        println!("a é foobar");
    }
}

Resumo

Parabéns! Você concluiu o laboratório If Let. Você pode praticar mais laboratórios no LabEx para aprimorar suas habilidades.