Médio Rust

Enum com dados e match com desestruturação

Enunciado

Defina um enum Mensagem com as variantes Sair, Mover { x: i32, y: i32 } e Escrever(String). Implemente uma função processar(msg: &Mensagem) que imprima uma mensagem adequada para cada variante. Use match exaustivo.

Requisitos

  • O enum Mensagem deve ter exatamente as três variantes especificadas.
  • A função processar deve usar match e tratar todas as variantes.
  • Para Mover, extraia x e y e imprima ambos.
  • Para Escrever, extraia o texto e imprima-o.
  • Para Sair, imprima uma mensagem de despedida.

Código inicial

enum Mensagem {
    Sair,
    Mover { x: i32, y: i32 },
    Escrever(String),
}

fn processar(msg: &Mensagem) {
    // Complete com match
    todo!()
}

fn main() {
    let m1 = Mensagem::Sair;
    let m2 = Mensagem::Mover { x: 10, y: 20 };
    let m3 = Mensagem::Escrever(String::from("Olá, Rust!"));
    processar(&m1);
    processar(&m2);
    processar(&m3);
}

Saída esperada

Até logo!
Movendo para (10, 20)
Texto: Olá, Rust!
Ver dica

No match, para a variante Mover, use o padrão Mensagem::Mover { x, y } para extrair os campos. Para Escrever, use Mensagem::Escrever(texto).

Mostrar solução
enum Mensagem {
    Sair,
    Mover { x: i32, y: i32 },
    Escrever(String),
}

fn processar(msg: &Mensagem) {
    match msg {
        Mensagem::Sair => println!("Até logo!"),
        Mensagem::Mover { x, y } => println!("Movendo para ({}, {})", x, y),
        Mensagem::Escrever(texto) => println!("Texto: {}", texto),
    }
}

fn main() {
    let m1 = Mensagem::Sair;
    let m2 = Mensagem::Mover { x: 10, y: 20 };
    let m3 = Mensagem::Escrever(String::from("Olá, Rust!"));
    processar(&m1);
    processar(&m2);
    processar(&m3);
}

Passo a passo

  1. O enum Mensagem tem três variantes: uma sem dados, uma com campos nomeados e uma com um String.
  2. A função processar recebe &Mensagem e usa match para verificar a variante.
  3. No braço Mensagem::Sair, apenas imprimimos a despedida.
  4. No braço Mensagem::Mover { x, y }, desestruturamos os campos x e y e os usamos na formatação.
  5. No braço Mensagem::Escrever(texto), extraímos o String e o imprimimos.
  6. O match é exaustivo, cobrindo todas as variantes.

Por que funciona

A desestruturação no match permite acessar os dados internos das variantes de forma direta. Como msg é uma referência, o Rust faz auto-deref e os padrões funcionam sem & explícito. A exaustividade garante que nenhum caso seja esquecido.

Erros comuns

  • Esquecer de tratar Sair: o compilador acusa non-exhaustive patterns.
  • Tentar mover texto para fora da referência: como msg é &Mensagem, texto é &String; se tentar usar texto como String diretamente, dará erro. Use texto como referência ou clone.
  • Não usar chaves no padrão Mover: Mensagem::Mover { x, y } é obrigatório para campos nomeados.

Outra forma de resolver

Usar if let para cada variante, mas seria repetitivo e não exaustivo. O match é mais claro.

Saída esperada

Até logo!
Movendo para (10, 20)
Texto: Olá, Rust!