Matching des variantes de données
Fait partie de la section Object Oriented Programming du Journey Rust de Coddy. Leçon 16 sur 61.
Dans la leçon précédente, tu as utilisé match dans les méthodes d’enum pour gérer différentes variantes. Concentrons-nous maintenant sur la manière dont match extrait réellement les données stockées dans ces variantes : une technique appelée destructuring.
Lorsque vous utilisez match sur une variante d’enum qui holds des données, vous pouvez lier ces données à des variables directement dans le motif :
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);
}
}
}
Chaque branche extrait les données différemment en fonction de la structure de la variante. Pour les variantes semblables à des structures, vous utilisez { field_name } pour extraire les champs nommés. Pour les variantes de tuple, vous utilisez des variables positionnelles comme (width, height).
Les noms de variables que tu choisis deviennent disponibles à l’intérieur de cette branche de match. C’est puissant, car tu vérifies simultanément quelle variante tu as et tu accèdes à sa charge utile.
Le compilateur garantit que vous handlez chaque variante et que les valeurs extraites sont immédiatement prêtes à l’emploi : aucune étape supplémentaire n’est nécessaire.
Défi
FacileConstruisons un processeur de command qui gère différents types de commandes utilisateur. Chaque command transporte des données différentes, et votre processeur utilisera la correspondance de motifs pour extraire ces données et produire des réponses appropriées.
Vous créerez deux fichiers pour organiser votre code :
command.rs: Define un enumCommandpublic avec trois variantes :Say: holds un seul messageString(syntaxe tuple)Move: holds des champs named :direction(String) etsteps(u32)Calculate: holds deux valeursi32représentant les nombres à additionner (syntaxe tuple)
executequi utilisematchpour destructure chaque variante et return unStringdécrivant l’action effectuée.main.rs: Importez votre module de command, créez une instance de chaque variante de command à l’aide des inputs fournis, puis appelez la méthodeexecutesur chacune pour afficher les results.
Votre méthode execute doit destructure chaque variante pour accéder à ses données et return des messages dans ces formats exacts :
- Pour
Say:Saying: {message} - Pour
Move:Moving {steps} steps {direction} - Pour
Calculate:{a} + {b} = {sum}
Votre sortie doit afficher le résultat de chaque command sur sa propre ligne :
Saying: {message}
Moving {steps} steps {direction}
{a} + {b} = {sum}Par exemple, avec un message Say "Hello world", un déplacement de 5 steps vers "north" et un calcul de 10 et 25, la sortie serait :
Saying: Hello world
Moving 5 steps north
10 + 25 = 35Vous recevrez cinq inputs : le message Say, la direction, le nombre de steps et les deux nombres à calculer.
Essayez vous-même
mod command;
use command::Command;
fn main() {
// Lire les entrées
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: Créer une commande Say en utilisant say_message et l'exécuter
// TODO: Créer une commande Move en utilisant direction et steps, et l'exécuter
// TODO: Créer une commande Calculate en utilisant num1 et num2, et l'exécuter
// TODO: Afficher les résultats de l'exécution de chaque commande
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Object Oriented Programming
1Méthodes et comportement
Introduction aux blocs d'implémentationLe paramètre SelfMéthodes mutablesFonctions associéesBlocs d'implémentation multiplesChaînage de méthodesRécapitulatif - Actions sur le rectangle4Projet : Animal virtuel
Définir l'animalNourrir l'animal7Traits standards
Le trait DebugLe trait DisplayClone et CopyLes traits d'égalitéRécapitulatif - Point affichable10Projet : Système de documents
Le trait DrawComposant texte2Encapsulation et modules
Bases des modulesLe mot-clé publicChamps privésGettersSettersRécapitulatif - Casier sécurisé5Généricité
Structures génériquesMéthodes génériquesPlusieurs types génériquesFonctions génériquesRécapitulatif - Point de coordonnées8Les Traits comme contraintes
Syntaxe des contraintes de traitContraintes multiplesLa clause whereRetourner des types avec des traitsRécapitulatif - Afficheur générique11Design Patterns en Rust
Le pattern NewtypeCompositionLe trait DropFrom et IntoRécapitulatif - Mock de Smart Pointer3Enums avancées
Enums avec donnéesMéthodes sur les EnumsMatching des variantes de donnéesL'Enum Option revisitéeRécapitulatif - Enum Shape6Définition des Traits
Qu'est-ce qu'un Trait ?Implémenter des TraitsImplémentations par défautRedéfinir les comportements par défautTraits avec paramètresRécapitulatif - Lecteur multimédiaEntraînez-vous par vous-même : Compilateur Rust en ligne