Noções Básicas de Traits
8 exemplos para você começar com traits - 5 básicos e 3 intermediários.
Pré-requisitos
Exemplos Básicos
1. Definir e Implementar um Trait
trait Greet {
fn greet(&self) -> String;
}
struct Person { name: String }
impl Greet for Person {
fn greet(&self) -> String {
format!("Olá, {}!", self.name)
}
}
fn main() {
let p = Person { name: "Ada".into() };
println!("{}", p.greet());
}- Traits definem comportamento compartilhado
impl Trait for Typefornece a implementação- Traits podem ter múltiplos métodos
- Regra do órfão:
impldeve estar no crate do trait ou do tipo
2. Corpos de Método Padrão
trait Log {
fn level(&self) -> &'static str { "info" }
fn msg(&self) -> &str;
}
struct Event(&'static str);
impl Log for Event {
fn msg(&self) -> &str { self.0 }
}- Métodos de trait podem ter padrões
- Implementadores substituem seletivamente
- Métodos padrão podem chamar outros métodos de trait
- Veja a página Métodos Padrão
3. Limites de Trait em Funções
use std::fmt::Display;
fn print_twice<T: Display>(value: T) {
println!("{value} {value}");
}
fn main() {
print_twice(42);
}T: Displayrestringe o parâmetro genérico- Limites permitem chamar métodos de trait em
T - Múltiplos limites com
+ - O compilador especializa genéricos (monomorfiza)
4. impl Trait em Parâmetros
use std::fmt::Display;
fn show(value: impl Display) {
println!("{value}");
}- Açúcar sintático para um único limite de trait
impl Display~=T: Displayanônimo- Assinaturas mais limpas para casos simples
+para múltiplos:impl Display + Clone
5. Retornar impl Trait
fn make_greeting() -> impl std::fmt::Display {
"hello"
}
fn main() {
println!("{}", make_greeting());
}- Oculta o tipo de retorno concreto
- O chamador usa apenas a interface do trait
- Um único tipo concreto por corpo de função é necessário
- Diferente de objetos de trait
dyn Trait
Exemplos Intermediários
6. Objetos de Trait dyn Trait
trait Drawable { fn draw(&self); }
struct Circle;
impl Drawable for Circle { fn draw(&self) { println!("círculo"); } }
fn render(shape: &dyn Drawable) {
shape.draw();
}
fn main() {
render(&Circle);
}- Despacho em tempo de execução via vtable
- Coleção heterogênea de tipos
- Regras de segurança de objeto se aplicam
- Veja a página Objetos de Trait
7. Supertraits
trait Outline: std::fmt::Display {
fn outline(&self) -> String;
}Outline: DisplayrequerDisplayprimeiro- Limites encadeiam comportamento
impl Outlinetambém deve implementarDisplay- Veja a página Supertraits
8. Preview de Tipos Associados
trait Iter {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}- Nomes de tipos associados nomeiam o tipo do elemento de saída
- Uma
implpor tipo (diferente de parâmetros genéricos de método) Iterator::Itemé o exemplo canônico- Veja a página Tipos Associados
Relacionado: Melhores Práticas de Traits e Genéricos
Versões da Stack: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, e Polars 0.46+.