Desestruturando

Como tuplas, structs e enums tambĂ©m podem ser desestruturados por meio de correspondĂȘncia:

Structs

struct Foo {
    x: (u32, u32),
    y: u32,
}

#[rustfmt::skip]
fn main() {
    let foo = Foo { x: (1, 2), y: 3 };
    match foo {
        Foo { x: (1, b), y } => println!("x.0 = 1, b = {b}, y = {y}"),
        Foo { y: 2, x: i }   => println!("y = 2, x = {i:?}"),
        Foo { y, .. }        => println!("y = {y}, outros campos foram ignorados"),
    }
}

Enums (EnumeraçÔes)

Os padrĂ”es tambĂ©m podem ser usados para vincular variĂĄveis a partes de seus valores. É assim que vocĂȘ inspeciona a estrutura de seus tipos. Vamos começar com um tipo enum simples:

enum Result {
    Ok(i32),
    Err(String),
}

fn divide_in_two(n: i32) -> Result {
    if n % 2 == 0 {
        Result::Ok(n / 2)
    } else {
        Result::Err(format!("nĂŁo Ă© possĂ­vel dividir {n} em duas partes iguais"))
    }
}

fn main() {
    let n = 100;
    match divide_in_two(n) {
        Result::Ok(half) => println!("{n} divido em dois Ă© {half}"),
        Result::Err(msg) => println!("desculpe, aconteceu um erro: {msg}"),
    }
}

Aqui usamos a verificação de correspondĂȘncia para desestruturar o valor contido em Result. Na primeira verificação de correspondĂȘncia, half estĂĄ vinculado ao valor dentro da variante Ok. Na segunda, msg estĂĄ vinculado Ă  mensagem de erro.

This slide should take about 8 minutes.

Structs

  • Modifique os valores em foo para corresponder com os outros padrĂ”es.
  • Adicione um novo campo a Foo e faça mudanças nos padrĂ”es conforme necessĂĄrio.
  • A diferença entre uma captura (capture) e uma expressĂŁo constante pode ser difĂ­cil de perceber. Tente modificar o 2 no segundo braço para uma variĂĄvel, e veja que, de forma sĂștil, nĂŁo funciona. Mude para const e veja funcionando novamente.

Enums (EnumeraçÔes)

Pontos chave:

  • A expressĂŁo if/else estĂĄ retornando um enum que Ă© posteriormente descompactado com um match.
  • VocĂȘ pode tentar adicionar uma terceira variante Ă  definição de Enum e exibir os erros ao executar o cĂłdigo. Aponte os lugares onde seu cĂłdigo agora Ă© “nĂŁo exaustivo” e como o compilador tenta lhe dar dicas.
  • Os valores nas variantes de uma enum sĂł podem ser acessados apĂłs uma correspondĂȘncia de padrĂŁo.
  • Demonstre o que acontece quando a busca nĂŁo abrange todas as possibilidades. Observe a vantagem que o compilador Rust fornece ao confirmar quando todos os casos sĂŁo tratados.
  • Salve o resultado de divide_in_two na variĂĄvel result e faça uma correspondĂȘncia de padrĂŁo (match) em um loop. Isso nĂŁo irĂĄ compilar porque msg Ă© consumido quando correspondido. Para corrigir, faça uma correspondĂȘncia de padrĂŁo em &result ao invĂ©s de result. Isso farĂĄ com que msg seja uma referĂȘncia, de forma que nĂŁo serĂĄ consumido. Essa “ergonomia de correspondĂȘncia” apareceu no Rust 2018. Se vocĂȘ quiser suportar versĂ”es mais antigas do Rust, substitua msg por ref msg no padrĂŁo.