Menu
Coddy logo textTech

Corrispondenza delle varianti con dati

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

Nella lezione precedente, hai usato match all'interno dei metodi degli enum per gestire varianti diverse. Ora concentriamoci su come match estrae effettivamente i dati memorizzati all'interno di queste varianti: una tecnica chiamata destrutturazione.

Quando esegui un match su una variante di un enum che contiene dati, puoi associare quei dati a variabili direttamente nel pattern:

enum Event {
    Click { x: i32, y: i32 },
    KeyPress(char),
    Resize(u32, u32),
}

fn handle_event(event: Event) {
    match event {
        Event::Click { x, y } => {
            println!("Clicked at ({}, {})", x, y);
        }
        Event::KeyPress(key) => {
            println!("Key pressed: {}", key);
        }
        Event::Resize(width, height) => {
            println!("Resized to {}x{}", width, height);
        }
    }
}

Ogni ramo estrae i dati in modo diverso in base alla struttura della variante. Per le varianti simili a struct, usi { field_name } per estrarre i campi con nome. Per le varianti di tupla, usi variabili posizionali come (width, height).

I nomi delle variabili che scegli diventano disponibili all'interno di quel ramo del match. Questo è potente perché allo stesso tempo verifichi quale variante hai e accedi al suo payload.

Il compilatore si assicura che tu gestisca ogni variante e i valori estratti sono subito pronti all’uso: non servono passaggi aggiuntivi.

challenge icon

Sfida

Facile

Creiamo un processore di comandi che gestisce diversi tipi di comandi utente. Ogni comando contiene dati diversi e il tuo processore userà il pattern matching per estrarre quei dati e produrre le risposte appropriate.

Creerai due file per organizzare il codice:

  • command.rs: Definisci un'enum pubblica Command con tre varianti:
    • Say: contiene un singolo messaggio String (sintassi a tupla)
    • Move: contiene campi con nome: direction (String) e steps (u32)
    • Calculate: contiene due valori i32 che rappresentano i numeri da sommare (sintassi a tupla)
    Poi implementa un metodo execute che usa match per destrutturare ogni variante e restituire una String che descrive l'azione eseguita.
  • main.rs: Importa il modulo dei comandi, crea un'istanza di ciascuna variante del comando usando gli input forniti e chiama il metodo execute su ciascuna per stampare i risultati.

Il metodo execute deve destrutturare ogni variante per accedere ai suoi dati e restituire messaggi nei seguenti formati esatti:

  • Per Say: Saying: {message}
  • Per Move: Moving {steps} steps {direction}
  • Per Calculate: {a} + {b} = {sum}

L'output deve mostrare il risultato di ciascun comando su una riga a sé:

Saying: {message}
Moving {steps} steps {direction}
{a} + {b} = {sum}

Per esempio, con un messaggio per Say pari a "Hello world", uno spostamento di 5 passi verso "north" e un calcolo con 10 e 25, l'output sarebbe:

Saying: Hello world
Moving 5 steps north
10 + 25 = 35

Riceverai cinque input: il messaggio per Say, la direzione, il numero di passi e i due numeri da calcolare.

Provalo tu

mod command;

use command::Command;

fn main() {
    // Leggi gli input
    let mut say_message = String::new();
    std::io::stdin().read_line(&mut say_message).expect("Failed to read line");
    let say_message = say_message.trim().to_string();

    let mut direction = String::new();
    std::io::stdin().read_line(&mut direction).expect("Failed to read line");
    let direction = direction.trim().to_string();

    let mut steps_input = String::new();
    std::io::stdin().read_line(&mut steps_input).expect("Failed to read line");
    let steps: u32 = steps_input.trim().parse().expect("Failed to parse steps");

    let mut num1_input = String::new();
    std::io::stdin().read_line(&mut num1_input).expect("Failed to read line");
    let num1: i32 = num1_input.trim().parse().expect("Failed to parse num1");

    let mut num2_input = String::new();
    std::io::stdin().read_line(&mut num2_input).expect("Failed to read line");
    let num2: i32 = num2_input.trim().parse().expect("Failed to parse num2");

    // TODO: Crea un comando Say usando say_message ed eseguilo
    
    // TODO: Crea un comando Move usando direction e steps, ed eseguilo
    
    // TODO: Crea un comando Calculate usando num1 e num2, ed eseguilo
    
    // TODO: Stampa i risultati dell'esecuzione di ciascun comando
}
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