Métodos em Enums
Parte da seção Programação Orientada a Objetos do Journey de Rust da Coddy. Lição 15 de 61.
Assim como as structs, os enums podem ter métodos definidos em blocos impl. Isso permite anexar comportamento diretamente ao seu tipo enum, facilitando o trabalho com diferentes variantes por meio de uma interface unificada.
Veja como adicionar um método ao enum Message da lição anterior:
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
}
impl Message {
fn describe(&self) -> String {
match self {
Message::Quit => String::from("Quit signal"),
Message::Move { x, y } => format!("Move to ({}, {})", x, y),
Message::Write(text) => format!("Message: {}", text),
}
}
}
O bloco impl Message funciona exatamente como funciona para structs. O método recebe &self para acessar a instância do enum. Dentro do método, você usa match para determinar com qual variante está lidando e retornar o resultado apropriado.
Chamar o método tem a mesma aparência independentemente da variante que você tenha:
fn main() {
let m1 = Message::Quit;
let m2 = Message::Move { x: 10, y: 20 };
println!("{}", m1.describe()); // Sinal de saída
println!("{}", m2.describe()); // Mover para (10, 20)
}
Esse padrão é poderoso porque quem chama não precisa saber qual variante tem. Basta chamar o método, e o enum cuida do restante internamente. O comportamento muda de acordo com a variante, mas a interface permanece consistente.
Desafio
FácilVamos criar um sistema de semáforo que usa uma enumeração com métodos para descrever o estado atual do sinal. Cada cor do semáforo carregará informações sobre quanto tempo dura, e um método fornecerá uma descrição legível.
Você criará dois arquivos para organizar seu código:
traffic.rs: Defina uma enumeração públicaTrafficLightcom três variantes:Red: contém umu32que representa os segundos de esperaYellow: contém umu32que representa os segundos de esperaGreen: contém umu32que representa os segundos para seguir
statusque retorna umaStringdescrevendo o semáforo. Usematchdentro do método para lidar com cada variante e incluir a duração na mensagem.main.rs: Inclua seu módulo de semáforo, crie instâncias de cada variante do semáforo e chame o métodostatusem cada uma para imprimir as descrições.
O método status deve retornar mensagens nestes formatos exatos:
- Para
Red:Stop for {seconds} seconds - Para
Yellow:Caution for {seconds} seconds - Para
Green:Go for {seconds} seconds
Sua saída deve exibir o status de cada luz em sua própria linha:
Stop for {seconds} seconds
Caution for {seconds} seconds
Go for {seconds} secondsPor exemplo, com um semáforo vermelho de 30 segundos, amarelo de 5 segundos e verde de 25 segundos, a saída seria:
Stop for 30 seconds
Caution for 5 seconds
Go for 25 secondsVocê receberá três entradas: a duração do semáforo vermelho, a duração do semáforo amarelo e a duração do semáforo verde.
Experimente você mesmo
mod traffic;
use traffic::TrafficLight;
fn main() {
// Ler entrada para as durações
let mut red_input = String::new();
std::io::stdin().read_line(&mut red_input).expect("Failed to read line");
let red_duration: u32 = red_input.trim().parse().expect("Invalid number");
let mut yellow_input = String::new();
std::io::stdin().read_line(&mut yellow_input).expect("Failed to read line");
let yellow_duration: u32 = yellow_input.trim().parse().expect("Invalid number");
let mut green_input = String::new();
std::io::stdin().read_line(&mut green_input).expect("Failed to read line");
let green_duration: u32 = green_input.trim().parse().expect("Invalid number");
// TODO: Criar instâncias de cada variante de TrafficLight com as durações de entrada
// TODO: Chamar o método status em cada luz e imprimir o resultado
}
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
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