Implementando Traits
Parte da seção Object Oriented Programming do Journey de Rust da Coddy. Lição 30 de 61.
Agora que você sabe como definir uma trait, vamos ver como fazer uma struct cumprir esse contrato. Implementar uma trait conecta o requisito abstrato ao comportamento concreto.
A sintaxe utiliza impl TraitName for StructName:
trait Speak {
fn speak(&self) -> String;
}
struct Dog {
name: String,
}
impl Speak for Dog {
fn speak(&self) -> String {
format!("{} says: Woof!", self.name)
}
}
O bloco impl Speak for Dog informa ao Rust que Dog está implementando a trait Speak. Dentro, você fornece o corpo real do método — é aqui que você define como um cachorro fala.
O poder das traits torna-se claro quando múltiplos tipos implementam a mesma:
struct Cat {
name: String,
}
impl Speak for Cat {
fn speak(&self) -> String {
format!("{} says: Meow!", self.name)
}
}
Tanto Dog quanto Cat agora compartilham a capacidade Speak, mas cada um fornece sua própria implementação única. Você pode chamar .speak() em qualquer um dos tipos:
let dog = Dog { name: String::from("Rex") };
let cat = Cat { name: String::from("Whiskers") };
println!("{}", dog.speak()); // Rex diz: Woof!
println!("{}", cat.speak()); // Whiskers diz: Meow!
Esta é a base do polimorfismo em Rust — tipos diferentes, mesma interface, comportamentos únicos.
Desafio
FácilVamos dar vida às traits implementando-as para diferentes tipos! Você criará uma trait Describable e a implementará para duas structs diferentes, cada uma fornecendo sua própria descrição única.
Você organizará seu código em três arquivos:
describable.rs: Defina uma trait públicaDescribablecom um métododescribe(&self) -> String.items.rs: Crie duas structs públicas que implementam sua trait:Bookcom um campo públicotitle(String)Moviecom um campo públiconame(String)
Describablecom seu próprio formato de descrição exclusivo.main.rs: Reúna seus módulos, crie instâncias de ambas as structs e chame seus métodosdescribepara mostrar como a mesma trait produz saídas diferentes para tipos diferentes.
Seu Book deve se descrever como Book: {title} e seu Movie deve se descrever como Film: {name}. Observe como cada tipo cumpre o mesmo contrato, mas com seu próprio comportamento!
No seu arquivo principal, crie um livro e um filme usando as duas entradas fornecidas e, em seguida, imprima suas descrições em linhas separadas.
Sua saída deve seguir este formato:
Book: {title}
Film: {name}Por exemplo, com as entradas 1984 e Inception:
Book: 1984
Film: InceptionVocê receberá duas entradas: um título de livro e um nome de filme.
Experimente você mesmo
mod describable;
mod items;
use describable::Describable;
use items::{Book, Movie};
fn main() {
// Ler entradas
let mut title = String::new();
std::io::stdin().read_line(&mut title).expect("Failed to read line");
let title = title.trim().to_string();
let mut name = String::new();
std::io::stdin().read_line(&mut name).expect("Failed to read line");
let name = name.trim().to_string();
// TODO: Criar uma instância de Book com o título
// TODO: Criar uma instância de Movie com o nome
// TODO: Imprimir a descrição do livro
// TODO: Imprimir a descrição do filme
}
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