Menu
Coddy logo textTech

Dopasowywanie wariantów danych

Część sekcji Programowanie obiektowe ścieżki Rust w Coddy. Lekcja 16 z 61.

W poprzedniej lekcji używasz match wewnątrz metod enum, aby obsługiwać różne warianty. Teraz skupimy się na tym, jak match faktycznie wyodrębnia dane przechowywane wewnątrz tych wariantów: technice zwanej destrukturyzacją.

Gdy dopasowujesz wariant wyliczenia, który przechowuje dane, możesz przypisać te dane do zmiennych bezpośrednio we wzorcu:

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

Każda gałąź wyodrębnia dane inaczej, zależnie od struktury wariantu. W przypadku wariantów podobnych do struktur używasz { field_name }, aby wyodrębnić nazwane pola. W przypadku wariantów krotkowych używasz zmiennych pozycyjnych, takich jak (width, height).

Wybrane przez ciebie nazwy zmiennych stają się dostępne wewnątrz tej gałęzi dopasowania. To potężne rozwiązanie, ponieważ jednocześnie sprawdzasz, który wariant masz, i uzyskujesz dostęp do jego danych.

Kompilator gwarantuje, że obsłużysz każdy wariant, a wyodrębnione wartości są od razu gotowe do użycia: nie potrzeba żadnych dodatkowych kroków.

challenge icon

Wyzwanie

Łatwy

Zbudujmy procesor poleceń, który obsługuje różne typy poleceń użytkownika. Każde polecenie zawiera inne dane, a procesor będzie używać dopasowania wzorców, aby wyodrębnić te dane i wygenerować odpowiednie odpowiedzi.

Utworzysz dwa pliki, aby uporządkować swój kod:

  • command.rs: Zdefiniuj publiczny typ wyliczeniowy Command z trzema wariantami:
    • Say: przechowuje pojedynczą wiadomość typu String (składnia krotkowa)
    • Move: przechowuje nazwane pola: direction (String) i steps (u32)
    • Calculate: przechowuje dwie wartości i32 reprezentujące liczby do dodania (składnia krotkowa)
    Następnie zaimplementuj metodę execute, która używa match, aby rozpakować każdy wariant i zwrócić wartość String opisującą wykonaną czynność.
  • main.rs: Zaimportuj moduł poleceń, utwórz po jednej instancji każdego wariantu polecenia, korzystając z podanych danych wejściowych, i wywołaj metodę execute dla każdej z nich, aby wypisać wyniki.

Metoda execute powinna rozpakowywać każdy wariant, aby uzyskać dostęp do jego danych, i zwracać komunikaty w dokładnie następujących formatach:

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

Wynik powinien wyświetlać rezultat każdego polecenia w osobnym wierszu:

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

Na przykład dla wiadomości polecenia Say "Hello world", polecenia Move z 5 krokami w kierunku "north" oraz obliczenia z użyciem 10 i 25, wynik wyglądałby tak:

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

Otrzymasz pięć danych wejściowych: wiadomość polecenia Say, kierunek, liczbę kroków oraz dwie liczby do obliczenia.

Spróbuj swoich sił

mod command;

use command::Command;

fn main() {
    // Odczytaj dane wejściowe
    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: Utwórz polecenie Say, używając say_message, i je wykonaj
    
    // TODO: Utwórz polecenie Move, używając direction i steps, i je wykonaj
    
    // TODO: Utwórz polecenie Calculate, używając num1 i num2, i je wykonaj
    
    // TODO: Wypisz wyniki wykonania każdego polecenia
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Rust online