Menu
Coddy logo textTech

Vincoli multipli

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

A volte un singolo vincolo di trait non basta. Potresti aver bisogno di un tipo generico che possa sia essere stampato sia fornire un riepilogo. Rust ti permette di richiedere più trait usando la sintassi +.

Ecco come specificare che un tipo deve implementare due trait:

use std::fmt::Display;

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

fn announce<T: Display + Summary>(item: T) {
    println!("Breaking news: {}", item);
    println!("Summary: {}", item.summarize());
}

Il vincolo T: Display + Summary significa «T deve implementare sia Display sia Summary». All'interno della funzione, puoi usare le funzionalità di entrambi i trait: stampare con {} (da Display) e chiamare summarize() (da Summary).

Puoi concatenare tutti i trait che ti servono:

fn process<T: Display + Summary + Clone>(item: T) {
    // Può stampare, riassumere E clonare
}

Questo schema è essenziale quando la tua funzione si basa su più comportamenti. Invece di accettare qualsiasi tipo e sperare che funzioni, dichiari esplicitamente quali capacità sono richieste e il compilatore le verifica in fase di compilazione.

challenge icon

Sfida

Facile

Costruiamo un sistema di ispezione dei prodotti che richiede che gli articoli abbiano più capacità! Creerai una funzione generica che accetta solo tipi che implementano sia un trait personalizzato sia un trait standard, dimostrando come la sintassi + combina più vincoli.

Organizzerai il codice in due file:

  • product.rs: Definisci un trait pubblico Inspectable con un metodo chiamato inspect che accetta &self e restituisce una String contenente i dettagli dell'ispezione. Poi crea una struct pubblica Gadget con i campi pubblici name (String) e serial (u32). Il tuo Gadget deve implementare sia Inspectable (restituendo Inspecting: {name}) sia std::fmt::Display (formattando come {name} (SN: {serial})). Infine, crea una funzione generica pubblica chiamata full_report che accetta qualsiasi tipo T che implementa sia Display sia Inspectable. Questa funzione deve stampare due righe: prima l'articolo usando il formattatore {}, poi il risultato della chiamata a inspect().
  • main.rs: Importa il tuo modulo product e crea un'istanza di Gadget usando gli input forniti. Chiama full_report con il tuo gadget per mostrare che soddisfa entrambi i requisiti dei trait.

Il vantaggio dei vincoli multipli è che la tua funzione full_report può usare le capacità di entrambi i trait, mostrando l'articolo in modo ordinato E ottenendo i dettagli dell'ispezione, il tutto garantito in fase di compilazione.

Il tuo output dovrebbe mostrare sia il formato di visualizzazione sia il risultato dell'ispezione:

{name} (SN: {serial})
Inspecting: {name}

Per esempio, con gli input Smartwatch e 98765:

Smartwatch (SN: 98765)
Inspecting: Smartwatch

Riceverai due input: il nome del gadget e il numero di serie (da analizzare come u32).

Provalo tu

mod product;

use product::{Gadget, full_report};

fn main() {
    // Leggi i dati di input
    let mut name = String::new();
    std::io::stdin().read_line(&mut name).expect("Failed to read line");
    let name = name.trim().to_string();
    
    let mut serial_input = String::new();
    std::io::stdin().read_line(&mut serial_input).expect("Failed to read line");
    let serial: u32 = serial_input.trim().parse().expect("Failed to parse serial");
    
    // TODO: Crea un'istanza di Gadget con il nome e il numero di serie
    
    // TODO: Chiama full_report con il tuo gadget
}
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