Menu
Coddy logo textTech

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.

challenge icon

Défi

Facile

Construisons 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 publique Command avec trois variantes :
    • Say : contient un seul message String (syntaxe tuple)
    • Move : contient des champs nommés : direction (String) et steps (u32)
    • Calculate : contient deux valeurs i32 représentant les nombres à additionner (syntaxe tuple)
    Implémentez ensuite une méthode execute qui utilise match pour déstructurer chaque variante et renvoyer une String dé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éthode execute sur 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 = 35

Vous 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
}
quiz iconTestez-vous

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

Entraînez-vous par vous-même : Compilateur Rust en ligne