Menu
Coddy logo textTech

Matching von Datenvarianten

Teil des Abschnitts Objektorientierte Programmierung der Rust-Journey von Coddy. Lektion 16 von 61.

In der vorherigen Lektion hast du match innerhalb von Enum-Methoden verwendet, um verschiedene Varianten zu behandeln. Nun konzentrieren wir uns darauf, wie match tatsächlich die in diesen Varianten gespeicherten Daten extrahiert: eine Technik namens Destrukturierung.

Wenn du eine Enum-Variante abgleichst, die Daten enthält, kannst du diese Daten direkt im Muster an Variablen binden:

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);
        }
    }
}

Jeder Arm extrahiert Daten unterschiedlich, abhängig von der Struktur der Variante. Für struct-ähnliche Varianten verwendest du { field_name }, um benannte Felder herauszuziehen. Für Tupelvarianten verwendest du Positionsvariablen wie (width, height).

Die Variablennamen, die du auswählst, werden innerhalb dieses match-Zweigs verfügbar. Das ist besonders praktisch, weil du gleichzeitig überprüfst, welche Variante vorliegt, und Zugriff auf deren Nutzlast erhältst.

Der Compiler stellt sicher, dass du jede Variante behandelst, und die extrahierten Werte sind sofort einsatzbereit: keine zusätzlichen Schritte erforderlich.

challenge icon

Aufgabe

Einfach

Wir erstellen einen Befehlsprozessor, der verschiedene Arten von Benutzerbefehlen verarbeitet. Jeder Befehl enthält unterschiedliche Daten, und dein Prozessor verwendet Pattern Matching, um diese Daten zu extrahieren und geeignete Antworten zu erzeugen.

Du erstellst zwei Dateien, um deinen Code zu organisieren:

  • command.rs: Definiere eine öffentliche Command-Enumeration mit drei Varianten:
    • Say: enthält eine einzelne String-Nachricht (Tupel-Syntax)
    • Move: enthält benannte Felder: direction (String) und steps (u32)
    • Calculate: enthält zwei i32-Werte, die zu addierende Zahlen darstellen (Tupel-Syntax)
    Implementiere anschließend eine execute-Methode, die match verwendet, um jede Variante zu destrukturieren und einen String zurückzugeben, der die ausgeführte Aktion beschreibt.
  • main.rs: Binde dein command-Modul ein, erstelle mithilfe der vorgegebenen Eingaben eine Instanz jeder Befehlsvariante und rufe für jede die execute-Methode auf, um die Ergebnisse auszugeben.

Deine execute-Methode sollte jede Variante destrukturieren, um auf ihre Daten zuzugreifen, und Nachrichten in diesen exakten Formaten zurückgeben:

  • Für Say: Saying: {message}
  • Für Move: Moving {steps} steps {direction}
  • Für Calculate: {a} + {b} = {sum}

Deine Ausgabe sollte das Ergebnis jedes Befehls in einer eigenen Zeile anzeigen:

Saying: {message}
Moving {steps} steps {direction}
{a} + {b} = {sum}

Wenn die Say-Nachricht beispielsweise "Hello world" lautet, eine Bewegung aus 5 Schritten in "north"-Richtung besteht und die Berechnung mit 10 und 25 durchgeführt wird, würde die Ausgabe folgendermaßen aussehen:

Saying: Hello world
Moving 5 steps north
10 + 25 = 35

Du erhältst fünf Eingaben: die Say-Nachricht, die Richtung, die Anzahl der Schritte und die beiden zu berechnenden Zahlen.

Probier es selbst

mod command;

use command::Command;

fn main() {
    // Eingaben lesen
    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: Erstelle einen Say-Befehl mit say_message und führe ihn aus
    
    // TODO: Erstelle einen Move-Befehl mit direction und steps und führe ihn aus
    
    // TODO: Erstelle einen Calculate-Befehl mit num1 und num2 und führe ihn aus
    
    // TODO: Gib die Ergebnisse jeder Befehlsausführung aus
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Rust-Compiler