Menu
Coddy logo textTech

Sintaxe de Restrições de Trait

Parte da seção Programação Orientada a Objetos do Journey de Rust da Coddy. Lição 40 de 61.

Até agora, você aprendeu a definir traits e implementá-los para structs. Você também trabalhou com genéricos para escrever código flexível. Agora é hora de combinar esses conceitos: usar traits para restringir quais tipos uma função genérica pode aceitar.

Considere uma função genérica que precisa chamar um método específico em seu parâmetro. Sem nenhuma restrição, Rust não garante que o tipo T tenha esse método:

fn print_info<T>(item: T) {
    println!("{}", item.summarize());  // Erro! T pode não ter summarize()
}

A solução é um limite de trait. Ao adicionar : TraitName após o parâmetro genérico, você informa ao Rust que T deve implementar essa trait:

trait Summary {
    fn summarize(&self) -> String;
}

fn print_info<T: Summary>(item: T) {
    println!("{}", item.summarize());  // Agora o Rust sabe que este método existe
}

A sintaxe <T: Summary> pode ser lida como “T é qualquer tipo que implementa Summary.” Agora, a função aceita apenas tipos que têm o comportamento necessário. Se você tentar passar um tipo que não implementa Summary, o compilador o rejeitará com um erro claro.

Esse padrão é poderoso porque permite escrever código genérico que ainda tem acesso a funcionalidades específicas. Sua função permanece flexível: ela funciona com qualquer tipo, mas apenas com tipos que fornecem o comportamento de que você precisa.

challenge icon

Desafio

Fácil

Vamos criar um sistema de notificações que usa limites de traits para garantir que somente mensagens formatadas corretamente possam ser enviadas! Você criará uma função genérica que aceita qualquer tipo que implemente uma trait específica, demonstrando como os limites de traits restringem parâmetros genéricos.

Você organizará seu código em dois arquivos:

  • notification.rs: Defina uma trait pública Notify com um método chamado message que recebe &self e retorna uma String. Em seguida, crie duas structs públicas que implementem essa trait:
    • Email: com um campo público subject (String). Seu método message deve retornar Email: {subject}
    • SMS: com um campo público content (String). Seu método message deve retornar SMS: {content}
    Por fim, crie uma função genérica pública chamada send_notification que aceite qualquer tipo T que implemente a trait Notify. Essa função deve imprimir o resultado da chamada de message() no item.
  • main.rs: Inclua seu módulo de notificações e use as entradas fornecidas para criar uma instância de Email e uma de SMS. Chame send_notification com cada uma para demonstrar que sua função genérica funciona com qualquer tipo que implemente Notify.

A principal ideia aqui é que send_notification não sabe qual é o tipo concreto recebido. Ela sabe apenas que o tipo pode produzir uma mensagem. O limite de trait T: Notify garante essa capacidade.

Sua saída deve mostrar as duas notificações sendo enviadas:

Email: {subject}
SMS: {content}

Por exemplo, com as entradas Meeting Tomorrow e On my way!:

Email: Meeting Tomorrow
SMS: On my way!

Você receberá duas entradas: o assunto do e-mail e o conteúdo do SMS.

Experimente você mesmo

mod notification;

use notification::{Email, SMS, send_notification};

fn main() {
    // Ler entradas
    let mut subject = String::new();
    std::io::stdin().read_line(&mut subject).expect("Failed to read line");
    let subject = subject.trim().to_string();
    
    let mut content = String::new();
    std::io::stdin().read_line(&mut content).expect("Failed to read line");
    let content = content.trim().to_string();
    
    // TODO: Crie uma instância de Email com o subject
    
    // TODO: Crie uma instância de SMS com o content
    
    // TODO: Chame send_notification com o email
    
    // TODO: Chame send_notification com o sms
}
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 Programação Orientada a Objetos

Pratique por conta própria: Compilador de Rust online