Menu
Coddy logo textTech

Implementações Padrão

Parte da seção Object Oriented Programming do Journey de Rust da Coddy — lição 31 de 61.

Até agora, cada método de trait que definimos foi apenas uma assinatura — um requisito sem corpo. Mas e se a maioria dos tipos que implementam uma trait usasse a mesma lógica? O Rust permite que você forneça uma implementação padrão diretamente na definição da trait.

Em vez de terminar a assinatura do método com um ponto e vírgula, você adiciona um corpo:

trait Greet {
    fn greet(&self) -> String {
        String::from("Hello there!")
    }
}

Agora, qualquer tipo que implemente Greet recebe automaticamente este método — sem escrever nenhum código no bloco impl:

struct Guest;

impl Greet for Guest {}

let visitor = Guest;
println!("{}", visitor.greet());  // Olá!

O impl Greet for Guest {} vazio é válido porque a trait já fornece o comportamento. A struct simplesmente "opta por participar" da trait e recebe o método padrão gratuitamente.

Este padrão é útil quando você deseja definir um comportamento compartilhado que funciona para a maioria dos casos. Tipos que precisam de algo diferente podem sobrescrever o padrão (o que você aprenderá a seguir), enquanto tipos que estão satisfeitos com o comportamento padrão não precisam se repetir.

challenge icon

Desafio

Fácil

Vamos explorar o poder das implementações padrão construindo um sistema de notificação! Você criará uma trait que fornece um comportamento padrão pronto para uso, para que os tipos possam aderir sem escrever código repetitivo.

Você organizará seu código em três arquivos:

  • notifiable.rs: Defina uma trait pública Notifiable com um método notify(&self) -> String que possui uma implementação padrão. O padrão deve retornar "You have a new notification!". Qualquer tipo que implementar esta trait receberá automaticamente este comportamento sem precisar escrever nada em seu bloco impl.
  • alerts.rs: Crie duas structs de unidade públicas simples que implementam sua trait:
    • EmailAlert — implementa Notifiable com um bloco impl vazio (usa o padrão)
    • SystemAlert — também implementa Notifiable com um bloco impl vazio (usa o padrão)
    Ambas as structs receberão automaticamente a mensagem de notificação padrão sem que você precise escrever nenhum corpo de método!
  • main.rs: Reúna seus módulos e demonstre como ambos os tipos de alerta compartilham o mesmo comportamento padrão. Crie instâncias de ambas as structs e chame seus métodos notify.

Em seu arquivo principal, crie um EmailAlert e um SystemAlert, e então imprima suas notificações em linhas separadas.

Sua saída deve ser:

You have a new notification!
You have a new notification!

Observe como ambos os tipos produzem uma saída idêntica — essa é a beleza das implementações padrão! Nenhuma das structs precisou escrever nenhum código para o método notify, mas ambas possuem um comportamento de notificação totalmente funcional. Na próxima lição, você aprenderá como sobrescrever esses padrões quando um tipo precisar de um comportamento personalizado.

Folha de consulta

Métodos de trait podem ter implementações padrão ao fornecer um corpo de método em vez de apenas uma assinatura:

trait Greet {
    fn greet(&self) -> String {
        String::from("Hello there!")
    }
}

Tipos que implementam a trait recebem automaticamente o comportamento padrão sem escrever nenhum código:

struct Guest;

impl Greet for Guest {}

let visitor = Guest;
println!("{}", visitor.greet());  // Hello there!

Um bloco impl vazio é válido quando a trait fornece implementações padrão. Isso permite que os tipos optem por um comportamento compartilhado sem repetição.

Experimente você mesmo

mod notifiable;
mod alerts;

use notifiable::Notifiable;
use alerts::{EmailAlert, SystemAlert};

fn main() {
    // TODO: Criar uma instância de EmailAlert
    
    // TODO: Criar uma instância de SystemAlert
    
    // TODO: Imprimir a notificação de EmailAlert
    
    // TODO: Imprimir a notificação de SystemAlert
}
quiz iconTeste seus conhecimentos

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