Menu
Coddy logo textTech

Sintassi dei vincoli sui trait

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

Finora hai imparato a definire i trait e a implementarli per le struct. Hai anche lavorato con i generics per scrivere codice flessibile. Ora è il momento di combinare questi concetti: usare i trait per vincolare i tipi che una funzione generica può accettare.

Considera una funzione generica che deve chiamare un metodo specifico sul suo parametro. Senza vincoli, Rust non garantisce che il tipo T abbia quel metodo:

fn print_info<T>(item: T) {
    println!("{}", item.summarize());  // ¡Error! T podría no tener summarize()
}

La soluzione è un vincolo di trait. Aggiungendo : TraitName dopo il parametro generico, dici a Rust che T deve implementare quel trait:

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

fn print_info<T: Summary>(item: T) {
    println!("{}", item.summarize());  // Ora Rust sa che questo metodo esiste
}

La sintassi <T: Summary> si legge come «T è un tipo qualsiasi che implementa Summary». Ora la funzione accetta solo i tipi che hanno il comportamento richiesto. Se provi a passare un tipo che non implementa Summary, il compilatore lo rifiuterà con un errore chiaro.

Questo schema è potente perché ti permette di scrivere codice generico che ha comunque accesso a funzionalità specifiche. La tua funzione rimane flessibile: funziona con qualsiasi tipo, ma solo con i tipi che forniscono il comportamento di cui hai bisogno.

challenge icon

Sfida

Facile

Costruiamo un sistema di notifiche che usa i vincoli dei trait per garantire che possano essere inviati solo messaggi formattati correttamente! Creerai una funzione generica che accetta qualsiasi tipo che implementi un trait specifico, dimostrando come i vincoli dei trait limitano i parametri generici.

Organizzerai il codice in due file:

  • notification.rs: Definisci un trait pubblico Notify con un metodo chiamato message che prende &self e restituisce una String. Poi crea due struct pubbliche che implementano questo trait:
    • Email: con un campo pubblico subject (String). Il suo metodo message dovrebbe restituire Email: {subject}
    • SMS: con un campo pubblico content (String). Il suo metodo message dovrebbe restituire SMS: {content}
    Infine, crea una funzione generica pubblica chiamata send_notification che accetta qualsiasi tipo T che implementi il trait Notify. Questa funzione dovrebbe stampare il risultato della chiamata a message() sull'elemento.
  • main.rs: Includi il modulo delle notifiche e usa gli input forniti per creare un'istanza di Email e una di SMS. Chiama send_notification con ciascuna per dimostrare che la tua funzione generica funziona con qualsiasi tipo che implementi Notify.

L'idea chiave è che send_notification non conosce il tipo concreto che riceve. Sa solo che il tipo può produrre un messaggio. Il vincolo del trait T: Notify garantisce questa capacità.

L'output dovrebbe mostrare entrambe le notifiche inviate:

Email: {subject}
SMS: {content}

Per esempio, con gli input Meeting Tomorrow e On my way!:

Email: Meeting Tomorrow
SMS: On my way!

Riceverai due input: l'oggetto dell'email e il contenuto dell'SMS.

Provalo tu

mod notification;

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

fn main() {
    // Leggi gli input
    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: Crea un'istanza di Email con subject
    
    // TODO: Crea un'istanza di SMS con content
    
    // TODO: Chiama send_notification con email
    
    // TODO: Chiama send_notification con sms
}
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