Conteúdos Variantes

Você pode definir enums mais ricos onde as variantes carregam dados. Você pode então usar a instrução match (corresponder) para extrair os dados de cada variante:

enum WebEvent {
    PageLoad,                 // Variante sem conteúdo
    KeyPress(char),           // Variante tupla
    Click { x: i64, y: i64 }, // Variante completa
}

#[rustfmt::skip]
fn inspect(event: WebEvent) {
    match event {
        WebEvent::PageLoad       => println!("página carregada"),
        WebEvent::KeyPress(c)    => println!("pressionou '{c}'"),
        WebEvent::Click { x, y } => println!("clicou em x={x}, y={y}"),
    }
}

fn main() {
    let load = WebEvent::PageLoad;
    let press = WebEvent::KeyPress('x');
    let click = WebEvent::Click { x: 20, y: 80 };

    inspect(load);
    inspect(press);
    inspect(click);
}
  • Os valores nas variantes de uma enum só podem ser acessados após uma correspondência de padrão. O padrão vincula referências aos campos no “braço” do match após =>.
    • A expressão é comparada com os padrões de cima a baixo. Não existe fall-through como em C ou C++.
    • A expressão match possui um valor. O valor é o da última expressão executada em um “braço” do match.
    • Começando do topo, nós procuramos qual padrão corresponde ao valor, e então executamos o código após a flecha. Quando uma correspondência é encontrada, nós paramos.
  • Demonstre o que acontece quando a busca não abrange todas as possibilidades. Mencione a vantagem que o compilador do Rust oferece confirmando quando todos os casos foram tratados.
  • match inspeciona um campo discriminant escondido na enum.
  • É possível recuperar o discriminante chamando std::mem::discriminant()
    • Isso é útil, por exemplo, ao implementar PartialEq para structs nas quais comparar valores de campos não afeta a igualdade.
  • WebEvent::Click { ... } não é exatamente o mesmo que WebEvent::Click(Click) com uma struct Click { ... } top-level. A versão no próprio local (inline) não permite implementar traits, por exemplo.