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.
Desafio
FácilVamos 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 enumCommandpúblico com três variantes:Say— contém uma única mensagemString(sintaxe de tupla)Move— contém campos nomeados:direction(String) esteps(u32)Calculate— contém dois valoresi32representando números para somar (sintaxe de tupla)
executeque usematchpara desestruturar cada variante e retornar umaStringdescrevendo 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étodoexecuteem 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 = 35Você 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
}
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
1Métodos e Comportamento
Introdução a Blocos de ImplementaçãoO Parâmetro SelfMétodos MutáveisFunções AssociadasMúltiplos Blocos de ImplementaçãoEncadeamento de MétodosRecapitulação - Ações de Retângulo4Projeto: Pet Virtual
Definindo o PetAlimentando o Pet7Traits Padrão
A Trait DebugA Trait DisplayClone e CopyTraits de IgualdadeRecapitulação - Ponto Imprimível10Projeto: Sistema de Documentos
A Trait DrawComponente de Texto2Encapsulamento e Módulos
Fundamentos de MódulosA Palavra-chave PublicCampos PrivadosGettersSettersRecapitulação - Cofre Seguro5Genéricos
Structs GenéricasMétodos GenéricosMúltiplos Tipos GenéricosFunções GenéricasRecapitulação - Ponto de Coordenada8Traits como Restrições
Sintaxe de Restrições de TraitRestrições MúltiplasA Cláusula WhereRetornando Tipos com TraitsRecapitulação - Impressora Genérica11Padrões de Projeto em Rust
Padrão NewtypeComposiçãoA Trait DropFrom e IntoRecapitulação - Mock de Smart Pointer3Enums Avançados
Enums com DadosMétodos em EnumsCorrespondência de Variantes de DadosO Enum Option RevisitadoRecapitulação - Enum Shape6Definição de Traits
O que é uma Trait?Implementando TraitsImplementações PadrãoSobrescrevendo PadrõesTraits com ParâmetrosRecapitulação - Media PlayerPratique por conta própria: Compilador de Rust online