Saltar al contenido principal
eLearner.app
Módulo 2 · Lección 2 de 24/14 en el curso~15 min
Lecciones del módulo (2/2)

Pattern matching, Option e Result

Rust possiede un meccanismo di controllo del flusso estremamente potente chiamato pattern matching. Permette di confrontare un valore con una serie di pattern ed eseguire codice in base al pattern corrispondente.

L'Istruzione match

L'istruzione match in Rust è simile allo switch in altri linguaggi, ma molto più potente e sicura. Il compilatore garantisce che il matching sia esaustivo, ossia che tutti i possibili casi siano gestiti:

Code
enum Direction {
    North,
    South,
    East,
    West,
}

let dir = Direction::East;

match dir {
    Direction::North => println!("Andiamo a Nord"),
    Direction::South => println!("Andiamo a Sud"),
    Direction::East => println!("Andiamo a Est"),
    Direction::West => println!("Andiamo a Ovest"),
}

Gestire l'assenza di valore: Option

Rust non ha il concetto di valore nullo (null o nil). Al suo posto, la libreria standard definisce un enum chiamato Option<T> che può contenere:

  • Some(T): contiene un valore di tipo T.
  • None: indica l'assenza di valore.
Code
let x: Option<i32> = Some(5);
let y: Option<i32> = None;

match x {
    Some(val) => println!("C'e un valore: {}", val),
    None => println!("Nessun valore trovato"),
}

Gestire gli errori ripristinabili: Result

Per operazioni che possono fallire (come la lettura di un file o la conversione di una stringa in numero), Rust usa l'enum Result<T, E> che possiede due varianti:

  • Ok(T): l'operazione è andata a buon fine e contiene il valore di successo T.
  • Err(E): l'operazione è fallita e contiene l'errore E.
Code
fn divide(numerator: f64, denominator: f64) -> Result<f64, String> {
    if denominator == 0.0 {
        Err(String::from("Divisione per zero!"))
    } else {
        Ok(numerator / denominator)
    }
}

Grazie al compilatore di Rust, sei obbligato a gestire il caso Err prima di poter accedere al valore dentro Ok, evitando moltissimi bug a runtime.

Il Pattern Jolly _ (Wildcard)

Quando lavoriamo con tipi di dato che hanno un gran numero di varianti (come gli interi), elencare tutti i casi in un match è impossibile. Rust permette di usare il carattere jolly _ per catturare tutti i casi rimanenti non definiti esplicitamente:

Code
let some_u8 = 3u8;
match some_u8 {
    1 => println!("Uno"),
    2 => println!("Due"),
    _ => println!("Qualcos'altro"), // Gestisce tutti gli altri valori
}

Prova tu

Ejercicio#rust.m2.l2.e1
Intentos: 0Cargando...

Dichiara una variabile maybe_value di tipo Option<i32> contenente Some(42). Usa un'istruzione match su maybe_value: se contiene Some(v) stampa 'value is: v' (con println!), se contiene None stampa 'no value'.

Cargando editor...
Mostrar pista

Scrivi un blocco `match maybe_value { Some(v) => println!('value is: {}', v), None => println!('no value') }`.

Solución disponible después de 3 intentos

Ejercicio#rust.m2.l2.e2
Intentos: 0Cargando...

Completa la funzione check_age in modo che restituisca Ok('Adult') se age è maggiore o uguale a 18, oppure Err('Minor') in caso contrario.

Cargando editor...
Mostrar pista

Usa un `if age >= 18`per decidere se restituire`Ok('Adult')`oppure`Err('Minor')`.

Solución disponible después de 3 intentos

Ejercicio#rust.m2.l2.e3
Intentos: 0Cargando...

Dichiara un enum chiamato Status contenente le varianti Active e Inactive. Nel main, dichiara una variabile current_status con valore Status::Active. Infine, usa un'istruzione match su current_status per stampare 'active' se lo stato è Active, o 'inactive' se lo stato è Inactive.

Cargando editor...
Mostrar pista

Definisci l'enum prima del main con `enum Status { Active, Inactive }`. Nel main usa `let current_status = Status::Active;`ed esegui il`match` sulle varianti.

Solución disponible después de 3 intentos