Menu
Coddy logo textTech

Correspondência de Variantes de Dados

Parte da seção Object Oriented Programming do Journey de Rust da Coddy. Lição 16 de 61.

Na lição anterior, você usou match dentro de métodos de enum para lidar com diferentes variantes. Agora vamos focar em como o match realmente extrai os dados armazenados dentro dessas variantes — uma técnica chamada desestruturação.

Quando você faz o match em uma variante de enum que contém dados, você pode vincular esses dados a variáveis diretamente no padrão:

enum Event {
    Click { x: i32, y: i32 },
    KeyPress(char),
    Resize(u32, u32),
}

fn handle_event(event: Event) {
    match event {
        Event::Click { x, y } => {
            println!("Clicked at ({}, {})", x, y);
        }
        Event::KeyPress(key) => {
            println!("Key pressed: {}", key);
        }
        Event::Resize(width, height) => {
            println!("Resized to {}x{}", width, height);
        }
    }
}

Cada braço extrai dados de forma diferente com base na estrutura da variante. Para variantes do tipo struct, você usa { field_name } para extrair campos nomeados. Para variantes de tupla, você usa variáveis posicionais como (width, height).

Os nomes de variáveis que você escolhe tornam-se disponíveis dentro daquele braço do match. Isso é poderoso porque você está simultaneamente verificando qual variante você tem e obtendo acesso ao seu payload.

O compilador garante que você trate cada variante, e os valores extraídos estão prontos para uso imediato — sem etapas extras necessárias.

challenge icon

Desafio

Fácil

Vamos construir um processador de comandos que lida com diferentes tipos de comandos de usuário. Cada comando carrega dados diferentes, e seu processador usará correspondência de padrões (pattern matching) para extrair esses dados e produzir as respostas apropriadas.

Você criará dois arquivos para organizar seu código:

  • command.rs: Defina um enum Command público com três variantes:
    • Say — contém uma única mensagem String (sintaxe de tupla)
    • Move — contém campos nomeados: direction (String) e steps (u32)
    • Calculate — contém dois valores i32 representando números para somar (sintaxe de tupla)
    Em seguida, implemente um método execute que use match para desestruturar cada variante e retornar uma String descrevendo a ação realizada.
  • main.rs: Importe seu módulo de comando, crie uma instância de cada variante de comando usando as entradas fornecidas e chame o método execute em cada uma para imprimir os resultados.

Seu método execute deve desestruturar cada variante para acessar seus dados e retornar mensagens nestes formatos exatos:

  • Para Say: Saying: {message}
  • Para Move: Moving {steps} steps {direction}
  • Para Calculate: {a} + {b} = {sum}

Sua saída deve exibir o resultado de cada comando em sua própria linha:

Saying: {message}
Moving {steps} steps {direction}
{a} + {b} = {sum}

Por exemplo, com uma mensagem de say de "Hello world", um move de 5 passos para "north", e um cálculo de 10 e 25, a saída seria:

Saying: Hello world
Moving 5 steps north
10 + 25 = 35

Você receberá cinco entradas: a mensagem de say, a direção, o número de passos e os dois números para calcular.

Experimente você mesmo

mod command;

use command::Command;

fn main() {
    // Ler as entradas
    let mut say_message = String::new();
    std::io::stdin().read_line(&mut say_message).expect("Failed to read line");
    let say_message = say_message.trim().to_string();

    let mut direction = String::new();
    std::io::stdin().read_line(&mut direction).expect("Failed to read line");
    let direction = direction.trim().to_string();

    let mut steps_input = String::new();
    std::io::stdin().read_line(&mut steps_input).expect("Failed to read line");
    let steps: u32 = steps_input.trim().parse().expect("Failed to parse steps");

    let mut num1_input = String::new();
    std::io::stdin().read_line(&mut num1_input).expect("Failed to read line");
    let num1: i32 = num1_input.trim().parse().expect("Failed to parse num1");

    let mut num2_input = String::new();
    std::io::stdin().read_line(&mut num2_input).expect("Failed to read line");
    let num2: i32 = num2_input.trim().parse().expect("Failed to parse num2");

    // TODO: Criar um comando Say usando say_message e executá-lo
    
    // TODO: Criar um comando Move usando direction e steps, e executá-lo
    
    // TODO: Criar um comando Calculate usando num1 e num2, e executá-lo
    
    // TODO: Imprimir os resultados de cada execução de comando
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Object Oriented Programming

Pratique por conta própria: Compilador de Rust online