Matching des variantes de données
Fait partie de la section Programmation Orientée Objet 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 commandes qui gère différents types de commandes utilisateur. Chaque commande contient des données différentes, et votre processeur utilisera la correspondance de motifs pour extraire ces données et produire les réponses appropriées.
Vous allez créer deux fichiers pour organiser votre code :
command.rs: définissez une énumération publiqueCommandavec trois variantes :Say: contient un seul messageString(syntaxe tuple)Move: contient des champs nommés :direction(String) etsteps(u32)Calculate: contient deux valeursi32représentant les nombres à additionner (syntaxe tuple)
executequi utilisematchpour déstructurer chaque variante et renvoyer uneStringdécrivant l’action effectuée.main.rs: ajoutez votre module de commande, créez une instance de chaque variante de commande à l’aide des entrées fournies, puis appelez la méthodeexecutesur chacune pour afficher les résultats.
Votre méthode execute doit déstructurer chaque variante pour accéder à ses données et renvoyer 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 commande sur sa propre ligne :
Saying: {message}
Moving {steps} steps {direction}
{a} + {b} = {sum}Par exemple, avec un message "Hello world" pour la commande say, un déplacement de 5 étapes vers "north" et un calcul avec 10 et 25, la sortie serait :
Saying: Hello world
Moving 5 steps north
10 + 25 = 35Vous recevrez cinq entrées : le message say, la direction, le nombre d’étapes 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 Programmation Orientée Objet
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