Metody typów wyliczeniowych
Część sekcji Programowanie obiektowe ścieżki Rust w Coddy. Lekcja 15 z 61.
Podobnie jak struktury, wyliczenia mogą mieć metody zdefiniowane w blokach impl. Pozwala to przypisać zachowanie bezpośrednio do typu wyliczeniowego i ułatwia pracę z różnymi wariantami za pośrednictwem jednolitego interfejsu.
Oto, jak dodać metodę do enuma Message z poprzedniej lekcji:
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
}
impl Message {
fn describe(&self) -> String {
match self {
Message::Quit => String::from("Quit signal"),
Message::Move { x, y } => format!("Move to ({}, {})", x, y),
Message::Write(text) => format!("Message: {}", text),
}
}
}
Blok impl Message działa dokładnie tak samo jak w przypadku struktur. Metoda przyjmuje &self, aby uzyskać dostęp do instancji enuma. Wewnątrz metody używasz match, aby określić, z którym wariantem masz do czynienia, i zwrócić odpowiedni wynik.
Wywołanie metody wygląda tak samo niezależnie od tego, który wariant masz:
fn main() {
let m1 = Message::Quit;
let m2 = Message::Move { x: 10, y: 20 };
println!("{}", m1.describe()); // Sygnał Quit
println!("{}", m2.describe()); // Move do (10, 20)
}
Ten wzorzec jest przydatny, ponieważ wywołujący nie musi wiedzieć, który wariant ma. Po prostu wywołuje metodę, a enum zajmuje się resztą wewnętrznie. Zachowanie zmienia się w zależności od wariantu, ale interfejs pozostaje spójny.
Wyzwanie
ŁatwyZbudujmy system sygnalizacji świetlnej, który używa wyliczenia z metodami opisującymi bieżący stan sygnału. Każdy kolor światła będzie przechowywać informację o tym, jak długo się świeci, a metoda zwróci czytelny dla człowieka opis.
Utworzysz dwa pliki, aby uporządkować swój kod:
traffic.rs: Zdefiniuj publiczne wyliczenieTrafficLightz trzema wariantami:Red: przechowuje wartośću32reprezentującą liczbę sekund oczekiwaniaYellow: przechowuje wartośću32reprezentującą liczbę sekund oczekiwaniaGreen: przechowuje wartośću32reprezentującą liczbę sekund, przez które można jechać
status, która zwraca wartośćStringopisującą światło. Użyj wewnątrz metodymatch, aby obsłużyć każdy wariant i uwzględnić czas trwania w komunikacie.main.rs: Zaimportuj moduł sygnalizacji świetlnej, utwórz instancje każdego wariantu światła i wywołaj dla każdej z nich metodęstatus, aby wypisać opisy.
Metoda status powinna zwracać komunikaty w dokładnie następujących formatach:
- Dla
Red:Stop for {seconds} seconds - Dla
Yellow:Caution for {seconds} seconds - Dla
Green:Go for {seconds} seconds
Wynik powinien wyświetlać stan każdego światła w osobnym wierszu:
Stop for {seconds} seconds
Caution for {seconds} seconds
Go for {seconds} secondsNa przykład dla czerwonego światła świecącego przez 30 sekund, żółtego przez 5 sekund i zielonego przez 25 sekund wynik wyglądałby tak:
Stop for 30 seconds
Caution for 5 seconds
Go for 25 secondsOtrzymasz trzy dane wejściowe: czas trwania czerwonego światła, czas trwania żółtego światła i czas trwania zielonego światła.
Spróbuj swoich sił
mod traffic;
use traffic::TrafficLight;
fn main() {
// Odczytaj dane wejściowe określające czas trwania
let mut red_input = String::new();
std::io::stdin().read_line(&mut red_input).expect("Failed to read line");
let red_duration: u32 = red_input.trim().parse().expect("Invalid number");
let mut yellow_input = String::new();
std::io::stdin().read_line(&mut yellow_input).expect("Failed to read line");
let yellow_duration: u32 = yellow_input.trim().parse().expect("Invalid number");
let mut green_input = String::new();
std::io::stdin().read_line(&mut green_input).expect("Failed to read line");
let green_duration: u32 = green_input.trim().parse().expect("Invalid number");
// TODO: Utwórz instancje każdego wariantu TrafficLight, używając podanych czasów trwania
// TODO: Wywołaj metodę status dla każdego światła i wypisz wynik
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Metody i zachowanie
Wprowadzenie do bloków implementacjiParametr selfMetody modyfikująceFunkcje powiązaneWiele bloków implementacjiŁańcuchowe wywoływanie metodPowtórzenie — działania na prostokącie4Projekt: Wirtualne zwierzątko
Definiowanie zwierzątkaKarmienie zwierzątka7Standardowe cechy
Cecha DebugCecha DisplayClone i CopyCechy równościPowtórka – punkt do wydrukowania10Projekt: System dokumentów
Trait DrawKomponent tekstowy2Hermetyzacja i moduły
Podstawy modułówSłowo kluczowe publicPola prywatneGetterySetteryPodsumowanie — bezpieczna skrytka5Typy generyczne
Struktury generyczneMetody generyczneWiele typów generycznychFunkcje generycznePodsumowanie – punkt współrzędnych8Cechy jako ograniczenia
Składnia ograniczeń cechWiele ograniczeńKlauzula whereZwracanie typów z użyciem cechPodsumowanie — generyczna drukarka11Wzorce projektowe w Rust
Wzorzec NewtypeKompozycjaTrait DropFrom i IntoPodsumowanie — atrapowy inteligentny wskaźnik3Zaawansowane typy wyliczeniowe
Typy wyliczeniowe z danymiMetody typów wyliczeniowychDopasowywanie wariantów danychTyp wyliczeniowy Option — powtórzeniePodsumowanie — typ wyliczeniowy Shape6Definiowanie cech
Czym jest cecha?Implementowanie cechImplementacje domyślneNadpisywanie wartości domyślnychCechy z parametramiPowtórzenie — odtwarzacz multimedialnyPoćwicz samodzielnie: Kompilator Rust online