Implementare i trait
Fa parte della sezione Programmazione orientata agli oggetti del percorso Rust di Coddy. Lezione 30 di 61.
Ora che sai come definire un trait, vediamo come fare in modo che una struct rispetti quel contratto. Implementare un trait collega il requisito astratto al comportamento concreto.
La sintassi usa impl TraitName for StructName:
trait Speak {
fn speak(&self) -> String;
}
struct Dog {
name: String,
}
impl Speak for Dog {
fn speak(&self) -> String {
format!("{} says: Woof!", self.name)
}
}
Il blocco impl Speak for Dog indica a Rust che Dog implementa il trait Speak. Al suo interno, fornisci il corpo effettivo del metodo. È qui che definisci come parla un cane.
La potenza dei trait diventa evidente quando più tipi implementano lo stesso trait:
struct Cat {
name: String,
}
impl Speak for Cat {
fn speak(&self) -> String {
format!("{} says: Meow!", self.name)
}
}
Sia Dog che Cat ora condividono la funzionalità Speak, ma ciascuno fornisce una propria implementazione. Puoi chiamare .speak() su entrambi i tipi:
let dog = Dog { name: String::from("Rex") };
let cat = Cat { name: String::from("Whiskers") };
println!("{}", dog.speak()); // Rex says: Woof!
println!("{}", cat.speak()); // Whiskers says: Meow!
Questa è la base del polimorfismo in Rust: tipi diversi, stessa interfaccia, comportamenti unici.
Sfida
FacileDiamo vita ai trait implementandoli per tipi diversi! Creerai un trait Describable e lo implementerai per due struct diversi, ciascuno dei quali fornirà una descrizione unica.
Organizzerai il codice in tre file:
describable.rs: Definisci un trait pubblicoDescribablecon un metododescribe(&self) -> String.items.rs: Crea due struct pubblici che implementano il tuo trait:Bookcon un campo pubblicotitle(String)Moviecon un campo pubbliconame(String)
Describablecon un proprio formato di descrizione unico.main.rs: Riunisci i tuoi moduli, crea istanze di entrambe le struct e chiama i loro metodidescribeper mostrare come lo stesso trait produce output diversi per tipi diversi.
La descrizione di Book dovrebbe essere Book: {title} e quella di Movie dovrebbe essere Film: {name}. Nota come ogni tipo rispetti lo stesso contratto, ma con un comportamento proprio!
Nel tuo file principale, crea un libro e un film usando i due input forniti, poi stampa le loro descrizioni su righe separate.
L'output dovrebbe seguire questo formato:
Book: {title}
Film: {name}Ad esempio, con gli input 1984 e Inception:
Book: 1984
Film: InceptionRiceverai due input: il titolo di un libro e il nome di un film.
Provalo tu
mod describable;
mod items;
use describable::Describable;
use items::{Book, Movie};
fn main() {
// Leggi gli input
let mut title = String::new();
std::io::stdin().read_line(&mut title).expect("Failed to read line");
let title = title.trim().to_string();
let mut name = String::new();
std::io::stdin().read_line(&mut name).expect("Failed to read line");
let name = name.trim().to_string();
// TODO: Crea un'istanza di Book con il titolo
// TODO: Crea un'istanza di Movie con il nome
// TODO: Stampa la descrizione del libro
// TODO: Stampa la descrizione del film
}
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
1Metodi e comportamento
Introduzione ai blocchi implIl parametro selfMetodi mutabiliFunzioni associateBlocchi impl multipliConcatenamento di metodiRiepilogo - Azioni sul rettangolo4Progetto: animale domestico virtuale
Definire l'animaleNutrire l'animale7Trait standard
Il trait DebugIl trait DisplayClone e CopyTrait di uguaglianzaRiepilogo - Punto stampabile10Progetto: sistema di documenti
Il trait DrawComponente di testo2Incapsulamento e moduli
Nozioni di base sui moduliLa parola chiave publicCampi privatiGetterSetterRiepilogo - Armadietto sicuro5Generics
Struct genericheMetodi genericiPiù tipi genericiFunzioni genericheRipasso - Punto di coordinate8I Trait come vincoli
Sintassi dei vincoli sui traitVincoli multipliLa clausola whereRestituire tipi con i traitRiepilogo - Stampante generica11Modelli di progettazione in Rust
Pattern NewtypeComposizioneIl trait DropFrom e IntoRipasso - Mock con smart pointer3Enumerazioni avanzate
Enumerazioni con datiMetodi sulle enumerazioniCorrispondenza delle varianti con datiL'enumerazione Option ripresaRiepilogo - enumerazione Shape6Definizione dei trait
Che cos’è un trait?Implementare i traitImplementazioni predefiniteSovrascrivere le implementazioni predefiniteTrait con parametriRiepilogo - Lettore multimedialeEsercitati da solo: Compilatore Rust online