Menu
Coddy logo textTech

Traits com Parâmetros

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

Até agora, nossos métodos de trait aceitaram apenas &self como parâmetro. Mas os métodos de trait podem aceitar parâmetros adicionais assim como métodos regulares — isso os torna muito mais úteis para operações do mundo real.

Ao definir uma trait, você pode incluir quaisquer parâmetros que precisar nas assinaturas dos métodos:

trait Calculator {
    fn add(&self, a: i32, b: i32) -> i32;
    fn multiply(&self, a: i32, b: i32) -> i32;
}

Este trait Calculator requer dois métodos, cada um aceitando dois inteiros além de &self. Qualquer tipo que implemente este trait deve fornecer ambas as operações com estas assinaturas exatas.

Veja como uma struct pode implementá-lo:

struct BasicCalc;

impl Calculator for BasicCalc {
    fn add(&self, a: i32, b: i32) -> i32 {
        a + b
    }
    
    fn multiply(&self, a: i32, b: i32) -> i32 {
        a * b
    }
}

Agora você pode usar esses métodos com argumentos:

let calc = BasicCalc;
println!("{}", calc.add(5, 3));       // 8
println!("{}", calc.multiply(4, 7));  // 28

O trait define quais parâmetros cada método aceita, enquanto a implementação define como esses parâmetros são usados. Isso permite que diferentes tipos realizem as mesmas operações de sua própria maneira—talvez um LoggingCalc pudesse imprimir cada operação antes de retornar o resultado.

challenge icon

Desafio

Fácil

Vamos construir um kit de ferramentas de manipulação de strings onde diferentes processadores podem transformar texto de suas próprias maneiras! Você criará uma trait TextProcessor com métodos que aceitam parâmetros e, em seguida, a implementará para dois tipos diferentes de processadores.

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

  • processor.rs: Defina uma trait pública TextProcessor com dois métodos que aceitam parâmetros:
    • repeat(&self, text: &str, times: u32) -> String — repete o texto fornecido um número especificado de vezes
    • truncate(&self, text: &str, max_len: usize) -> String — encurta o texto para o comprimento máximo especificado
  • processors.rs: Crie duas structs públicas que implementam sua trait:
    • SimpleProcessor — uma unit struct que repete o texto com espaços entre cada repetição (ex: "Hi" repetido 3 vezes torna-se "Hi Hi Hi") e trunca simplesmente cortando no comprimento máximo
    • FancyProcessor — uma unit struct que repete o texto com " * " entre as repetições (ex: "Hi" repetido 3 vezes torna-se "Hi * Hi * Hi") e trunca adicionando "..." se o texto foi encurtado (apenas se o texto original for maior que max_len)
  • main.rs: Reúna seus módulos e demonstre como os mesmos métodos da trait produzem resultados diferentes dependendo de qual processador você usa.

No seu arquivo principal, crie ambos os processadores e use as entradas para testá-los. Você receberá três entradas: uma string de texto, uma contagem de repetições e um comprimento máximo.

Imprima quatro linhas mostrando o comportamento de cada processador:

Simple repeat: {result}
Simple truncate: {result}
Fancy repeat: {result}
Fancy truncate: {result}

Por exemplo, com as entradas Hello, 3, e 4:

Simple repeat: Hello Hello Hello
Simple truncate: Hell
Fancy repeat: Hello * Hello * Hello
Fancy truncate: Hell...

Observe como ambos os processadores cumprem o mesmo contrato TextProcessor, mas cada um transforma o texto de sua maneira única. A trait define quais parâmetros os métodos aceitam, enquanto cada implementação decide como usá-los!

Você receberá três entradas: o texto a ser processado, o número de repetições (converta para u32) e o comprimento máximo para truncamento (converta para usize).

Folha de consulta

Métodos de trait podem aceitar parâmetros adicionais além de &self:

trait Calculator {
    fn add(&self, a: i32, b: i32) -> i32;
    fn multiply(&self, a: i32, b: i32) -> i32;
}

Implementando uma trait com parâmetros:

struct BasicCalc;

impl Calculator for BasicCalc {
    fn add(&self, a: i32, b: i32) -> i32 {
        a + b
    }
    
    fn multiply(&self, a: i32, b: i32) -> i32 {
        a * b
    }
}

Usando métodos de trait com argumentos:

let calc = BasicCalc;
println!("{}", calc.add(5, 3));       // 8
println!("{}", calc.multiply(4, 7));  // 28

A trait define quais parâmetros cada método aceita, enquanto a implementação define como esses parâmetros são usados.

Experimente você mesmo

mod processor;
mod processors;

use processor::TextProcessor;
use processors::{SimpleProcessor, FancyProcessor};

fn main() {
    // Ler as entradas
    let mut text = String::new();
    std::io::stdin().read_line(&mut text).expect("Failed to read line");
    let text = text.trim();
    
    let mut times_input = String::new();
    std::io::stdin().read_line(&mut times_input).expect("Failed to read line");
    let times: u32 = times_input.trim().parse().expect("Failed to parse times");
    
    let mut max_len_input = String::new();
    std::io::stdin().read_line(&mut max_len_input).expect("Failed to read line");
    let max_len: usize = max_len_input.trim().parse().expect("Failed to parse max_len");
    
    // Criar processadores
    let simple = SimpleProcessor;
    let fancy = FancyProcessor;
    
    // TODO: Usar os processadores para transformar o texto e imprimir os resultados
    // Imprimir quatro linhas:
    // Simple repeat: {result}
    // Simple truncate: {result}
    // Fancy repeat: {result}
    // Fancy truncate: {result}
}
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