Leçons du module (2/2)
Pattern matching, Option et Result
Rust possède un mécanisme de contrôle de flux extrêmement puissant appelé pattern matching (filtrage par motif). Il permet de comparer une valeur à une série de motifs et d'exécuter du code en fonction du motif correspondant.
L'Instruction match
L'instruction match en Rust est similaire au switch dans d'autres langages, mais elle est beaucoup plus puissante et sûre. Le compilateur garantit que le filtrage est exhaustif, c'est-à-dire que tous les cas possibles sont gérés :
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"),
}
Gérer l'absence de valeur : Option
Rust n'a pas le concept de valeur nulle (null ou nil). À la place, la bibliothèque standard définit un enum appelé Option<T> qui peut contenir :
Some(T): contient une valeur de typeT.None: indique l'absence de valeur.
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"),
}
Gérer les erreurs récupérables : Result
Pour les opérations susceptibles d'échouer (comme la lecture d'un fichier ou la conversion d'une chaîne en nombre), Rust utilise l'enum Result<T, E> qui possède deux variantes :
Ok(T): l'opération a réussi et contient la valeur de succèsT.Err(E): l'operazione a échoué et contient l'erreurE.
fn divide(numerator: f64, denominator: f64) -> Result<f64, String> {
if denominator == 0.0 {
Err(String::from("Divisione per zero!"))
} else {
Ok(numerator / denominator)
}
}
Grâce au compilateur de Rust, vous êtes obligé de gérer le cas Err avant de pouvoir accéder à la valeur dans Ok, ce qui évite de nombreux bugs à l'exécution.
Le Motif Joker _ (Wildcard)
Lorsque nous travaillons avec des types de données qui ont un grand nombre de variantes (comme les entiers), énumérer tous les cas dans un match est impossible. Rust permet d'utiliser le caractère joker _ pour capturer tous les cas restants qui ne sont pas définis explicitement :
let some_u8 = 3u8;
match some_u8 {
1 => println!("Uno"),
2 => println!("Due"),
_ => println!("Qualcos'altro"), // Gestisce tutti gli altri valori
}
À toi de jouer
Déclarez une variable maybe_value de type Option<i32> contenant Some(42). Utilisez une instruction match sur maybe_value : si elle contient Some(v), affichez 'value is: v' (avec println!), si elle contient None, affichez 'no value'.
Afficher l'indice
Écrivez un bloc `match maybe_value { Some(v) => println!('value is: {}', v), None => println!('no value') }`.
Solution disponible après 3 tentatives
Complétez la fonction check_age de manière à ce qu'elle renvoie Ok('Adult') si age est supérieur ou égal à 18, ou Err('Minor') dans le cas contraire.
Afficher l'indice
Utilisez un `if age >= 18`pour décider de renvoyer`Ok('Adult')`ou`Err('Minor')`.
Solution disponible après 3 tentatives
Déclarez un enum nommé Status contenant les variantes Active et Inactive. Dans le main, déclarez une variable current_status avec la valeur Status::Active. Enfin, utilisez une instruction match sur current_status pour afficher 'active' si l'état est Active, ou 'inactive' si l'état est Inactive.
Afficher l'indice
Définissez l'enum avant le main avec `enum Status { Active, Inactive }`. Dans le main, utilisez `let current_status = Status::Active;`et effectuez le`match` sur les variantes.
Solution disponible après 3 tentatives