Metodi sulle enumerazioni
Fa parte della sezione Programmazione orientata agli oggetti del percorso Rust di Coddy. Lezione 15 di 61.
Proprio come le struct, gli enum possono avere metodi definiti nei blocchi impl. Questo ti permette di associare un comportamento direttamente al tuo tipo enum, facilitando il lavoro con le diverse varianti attraverso un'interfaccia unificata.
Ecco come aggiungere un metodo all'enum Message della lezione precedente:
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
}
impl Message {
fn describe(&self) -> String {
match self {
Message::Quit => String::from("Quit signal"),
Message::Move { x, y } => format!("Move to ({}, {})", x, y),
Message::Write(text) => format!("Message: {}", text),
}
}
}
Il blocco impl Message funziona esattamente come per le struct. Il metodo accetta &self per accedere all’istanza dell’enum. All’interno del metodo, usi match per determinare quale variante stai gestendo e restituire il risultato appropriato.
La chiamata al metodo è identica indipendentemente dalla variante che hai:
fn main() {
let m1 = Message::Quit;
let m2 = Message::Move { x: 10, y: 20 };
println!("{}", m1.describe()); // Señal de salida
println!("{}", m2.describe()); // Mover a (10, 20)
}
Questo schema è potente perché chi chiama non deve sapere quale variante ha. Gli basta chiamare il metodo e l'enum gestisce internamente il resto. Il comportamento cambia in base alla variante, ma l'interfaccia rimane coerente.
Sfida
FacileCostruiamo un sistema di semafori che usa un enum con metodi per descrivere lo stato attuale del segnale. Ogni colore del semaforo conterrà informazioni sulla sua durata e un metodo fornirà una descrizione leggibile.
Creerai due file per organizzare il codice:
traffic.rs: definisci un enum pubblicoTrafficLightcon tre varianti:Red: contiene unu32che rappresenta i secondi di attesaYellow: contiene unu32che rappresenta i secondi di attesaGreen: contiene unu32che rappresenta i secondi per procedere
statusche restituisce unaStringche descrive il semaforo. Usamatchall'interno del metodo per gestire ogni variante e includi la durata nel messaggio.main.rs: importa il tuo modulo del semaforo, crea istanze di ogni variante e chiama il metodostatussu ciascuna per stampare le descrizioni.
Il metodo status dovrebbe restituire messaggi in questi formati esatti:
- Per
Red:Stop for {seconds} seconds - Per
Yellow:Caution for {seconds} seconds - Per
Green:Go for {seconds} seconds
L'output dovrebbe mostrare lo stato di ogni semaforo su una riga separata:
Stop for {seconds} seconds
Caution for {seconds} seconds
Go for {seconds} secondsAd esempio, con una luce rossa di 30 secondi, una gialla di 5 secondi e una verde di 25 secondi, l'output sarebbe:
Stop for 30 seconds
Caution for 5 seconds
Go for 25 secondsRiceverai tre input: la durata della luce rossa, la durata della luce gialla e la durata della luce verde.
Provalo tu
mod traffic;
use traffic::TrafficLight;
fn main() {
// Leggi i valori di input per le durate
let mut red_input = String::new();
std::io::stdin().read_line(&mut red_input).expect("Failed to read line");
let red_duration: u32 = red_input.trim().parse().expect("Invalid number");
let mut yellow_input = String::new();
std::io::stdin().read_line(&mut yellow_input).expect("Failed to read line");
let yellow_duration: u32 = yellow_input.trim().parse().expect("Invalid number");
let mut green_input = String::new();
std::io::stdin().read_line(&mut green_input).expect("Failed to read line");
let green_duration: u32 = green_input.trim().parse().expect("Invalid number");
// TODO: Crea un'istanza di ogni variante di TrafficLight usando le durate inserite
// TODO: Chiama il metodo status su ogni semaforo e stampa il risultato
}
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