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.
Folha de consulta
A correspondência de padrões com match permite que você desestruture variantes de enum e extraia seus dados diretamente no padrão.
Para variantes de tupla, use variáveis posicionais:
enum Event {
KeyPress(char),
Resize(u32, u32),
}
match event {
Event::KeyPress(key) => {
println!("Key: {}", key);
}
Event::Resize(width, height) => {
println!("{}x{}", width, height);
}
}Para variantes do tipo struct, use a sintaxe de campos nomeados:
enum Event {
Click { x: i32, y: i32 },
}
match event {
Event::Click { x, y } => {
println!("Clicked at ({}, {})", x, y);
}
}As variáveis extraídas tornam-se disponíveis dentro de seu respectivo braço de correspondência, permitindo que você verifique o tipo da variante e acesse seus dados simultaneamente.
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 Player