Menu
Coddy logo textTech

Correspondência de Variantes de Dados

Parte da seção Programação Orientada a Objetos 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 nos concentrar em como match realmente extrai os dados armazenados nessas variantes: uma técnica chamada desestruturação.

Quando você usa match em uma variante de enum que contém dados, 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 semelhantes a structs, 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ê escolher ficam disponíveis dentro desse braço de match. Isso é poderoso porque você verifica simultaneamente qual variante possui e obtém acesso aos dados associados a ela.

O compilador garante que você trate todas as variantes, e os valores extraídos estão prontos para uso imediato: nenhuma etapa extra é necessária.

challenge icon

Desafio

Fácil

Vamos criar um processador de comandos que lide com diferentes tipos de comandos do usuário. Cada comando contém dados diferentes, e seu processador usará correspondência de padrões para extrair esses dados e produzir respostas apropriadas.

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

  • command.rs: defina um enum público Command 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 a serem somados (sintaxe de tupla)
    Em seguida, implemente um método execute que use match para desestruturar cada variante e retorne uma String descrevendo a ação realizada.
  • main.rs: inclua seu módulo de comandos, 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 say de "Hello world", um movimento de 5 passos na direção "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 say, a direção, o número de passos e os dois números a serem calculados.

Experimente você mesmo

mod command;

use command::Command;

fn main() {
    // Ler 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 Programação Orientada a Objetos

Pratique por conta própria: Compilador de Rust online