Rust Tipos Intermediário
Traits
Uma trait em Rust descreve um conjunto de comportamentos que um tipo pode implementar. Ela é parecida com uma interface de outras linguagens: define assinaturas de métodos que o tipo precisa fornecer. Qualquer tipo — struct, enum ou até tipos primitivos — pode implementar uma trait.
Para implementar uma trait usamos impl NomeDaTrait for Tipo { ... }. A partir daí, os métodos da trait podem ser chamados como métodos normais do tipo. Traits permitem escrever código genérico que funciona com qualquer tipo que tenha o comportamento desejado, usando T: Trait ou impl Trait.
Traits também podem ter métodos padrão, isto é, implementações prontas que o tipo pode usar ou sobrescrever. Isso é útil para evitar repetição: o tipo só implementa o que é específico dele. Na biblioteca padrão existem várias traits importantes, como Display, Debug, Clone, PartialEq e Iterator.
Pontos-chave
- Uma trait define comportamentos que tipos podem compartilhar, sem herança de classes.
- Implementa-se com
impl Trait for Tipo { ... }e o tipo passa a ter os métodos da trait. - Métodos padrão têm corpo na própria trait e podem ser sobrescritos pelo tipo.
- Traits da std como
Display,CloneePartialEqpodem ser derivadas ou implementadas manualmente. - Funções genéricas podem exigir uma trait com a sintaxe
T: Traitouimpl Trait.
// Trait com um método obrigatório e um método padrão.
trait Animal {
fn nome(&self) -> String; // obrigatório
// método padrão: usa nome(), então quem implementa ganha de graça
fn apresentar(&self) -> String {
format!("Olá, eu sou {}", self.nome())
}
}
struct Cachorro;
struct Gato;
impl Animal for Cachorro {
fn nome(&self) -> String {
String::from("Rex")
}
}
impl Animal for Gato {
fn nome(&self) -> String {
String::from("Mimi")
}
// sobrescreve o método padrão
fn apresentar(&self) -> String {
format!("Miau! Eu sou {}", self.nome())
}
}
// Função genérica que aceita qualquer tipo que implemente Animal.
fn saudar<T: Animal>(animal: &T) {
println!("{}", animal.apresentar());
}
fn main() {
let c = Cachorro;
let g = Gato;
saudar(&c);
saudar(&g);
}