Menu
Coddy logo textTech

Trait con parametri

Fa parte della sezione Programmazione orientata agli oggetti del percorso Rust di Coddy. Lezione 33 di 61.

Finora, i nostri metodi dei trait hanno accettato solo &self come parametro. Ma i metodi dei trait possono accettare parametri aggiuntivi, proprio come i metodi normali. Questo li rende molto più utili per le operazioni del mondo reale.

Quando definisci un trait, puoi includere tutti i parametri necessari nelle firme dei metodi:

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

Questo trait Calculator richiede due metodi, ciascuno dei quali accetta due interi oltre a &self. Qualsiasi tipo che implementi questo trait deve fornire entrambe le operazioni con queste firme esatte.

Ecco come una struct potrebbe implementarlo:

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
    }
}

Ora puoi usare questi metodi con argomenti:

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

Il trait definisce quali parametri accetta ciascun metodo, mentre l’implementazione definisce come vengono utilizzati quei parametri. Questo consente a tipi diversi di eseguire le stesse operazioni a modo loro: magari un LoggingCalc potrebbe stampare ogni operazione prima di restituire il risultato.

challenge icon

Sfida

Facile

Costruiamo un toolkit per la manipolazione delle stringhe in cui diversi processori possono trasformare il testo a modo loro! Creerai un trait TextProcessor con metodi che accettano parametri, poi lo implementerai per due tipi di processore diversi.

Organizzerai il codice in tre file:

  • processor.rs: Definisci un trait pubblico TextProcessor con due metodi che accettano parametri:
    • repeat(&self, text: &str, times: u32) -> String: ripete il testo specificato per un determinato numero di volte
    • truncate(&self, text: &str, max_len: usize) -> String: accorcia il testo fino alla lunghezza massima specificata
  • processors.rs: Crea due struct pubbliche che implementano il tuo trait:
    • SimpleProcessor: una struct unitaria che ripete il testo inserendo spazi tra ogni ripetizione (ad esempio, "Hi" ripetuto 3 volte diventa "Hi Hi Hi") e tronca semplicemente il testo al raggiungimento della lunghezza massima
    • FancyProcessor: una struct unitaria che ripete il testo inserendo " * " tra le ripetizioni (ad esempio, "Hi" ripetuto 3 volte diventa "Hi * Hi * Hi") e tronca il testo aggiungendo "..." se è stato accorciato (solo se il testo originale era più lungo di max_len)
  • main.rs: Riunisci i tuoi moduli e mostra come gli stessi metodi del trait producono risultati diversi a seconda del processore utilizzato.

Nel file principale, crea entrambi i processori e usa gli input per testarli. Riceverai tre input: una stringa di testo, un numero di ripetizioni e una lunghezza massima.

Stampa quattro righe che mostrino il comportamento di ciascun processore:

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

Ad esempio, con gli input Hello, 3 e 4:

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

Nota come entrambi i processori rispettino lo stesso contratto TextProcessor, ma ciascuno trasformi il testo a modo suo. Il trait definisce quali parametri accettano i metodi, mentre ogni implementazione decide come usarli!

Riceverai tre input: il testo da elaborare, il numero di ripetizioni (da analizzare come u32) e la lunghezza massima per il troncamento (da analizzare come usize).

Provalo tu

mod processor;
mod processors;

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

fn main() {
    // Leggi gli input
    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");
    
    // Crea i processori
    let simple = SimpleProcessor;
    let fancy = FancyProcessor;
    
    // TODO: Usa i processori per trasformare il testo e stampare i risultati
    // Stampa quattro righe:
    // Simple repeat: {result}
    // Simple truncate: {result}
    // Fancy repeat: {result}
    // Fancy truncate: {result}
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Rust online