Wiele ograniczeń
Część sekcji Programowanie obiektowe ścieżki Rust w Coddy. Lekcja 41 z 61.
Czasami pojedyncze ograniczenie cechy nie wystarcza. Możesz potrzebować typu generycznego, który można zarówno wypisać i który udostępnia podsumowanie. Rust pozwala wymagać wielu cech za pomocą składni +.
Oto jak określić, że typ musi implementować dwa traitsy:
use std::fmt::Display;
trait Summary {
fn summarize(&self) -> String;
}
fn announce<T: Display + Summary>(item: T) {
println!("Breaking news: {}", item);
println!("Summary: {}", item.summarize());
}
Ograniczenie T: Display + Summary oznacza „T musi implementować zarówno Display, jak i Summary”. Wewnątrz funkcji możesz korzystać z możliwości obu cech: drukować za pomocą {} (z Display) i wywoływać summarize() (z Summary).
Możesz łączyć tyle cech, ile potrzebujesz:
fn process<T: Display + Summary + Clone>(item: T) {
// Może wyświetlać, podsumowywać ORAZ klonować
}
Ten wzorzec jest niezbędny, gdy Twoja funkcja opiera się na wielu zachowaniach. Zamiast akceptować dowolny typ i mieć nadzieję, że zadziała, jawnie deklarujesz dokładnie, jakie możliwości są wymagane, a kompilator sprawdza to podczas kompilacji.
Wyzwanie
ŁatwyStwórzmy system inspekcji produktów, który wymaga od elementów wielu możliwości! Utworzysz funkcję generyczną, która akceptuje wyłącznie typy implementujące zarówno niestandardowy trait, jak i standardowy trait, pokazując, jak składnia + łączy wiele ograniczeń.
Podzielisz swój kod na dwa pliki:
product.rs: Zdefiniuj publiczny traitInspectablez metodą o nazwieinspect, która przyjmuje&selfi zwracaStringzawierający szczegóły inspekcji. Następnie utwórz publiczną strukturęGadgetz publicznymi polaminame(String) iserial(u32). Twoja struktura Gadget powinna implementować zarównoInspectable(zwracającInspecting: {name}), jak istd::fmt::Display(formatując wynik jako{name} (SN: {serial})). Na koniec utwórz publiczną funkcję generyczną o nazwiefull_report, która przyjmuje dowolny typTimplementujący zarównoDisplay, jak iInspectable. Funkcja powinna wypisać dwa wiersze: najpierw element przy użyciu formatera{}, a następnie wynik wywołaniainspect().main.rs: Dołącz moduł produktu i utwórz instancjęGadgetna podstawie podanych danych wejściowych. Wywołajfull_reportze swoim gadżetem, aby pokazać, że spełnia on wymagania obu traitów.
Zaletą wielu ograniczeń jest to, że funkcja full_report może korzystać z możliwości obu traitów, ładnie wyświetlając element ORAZ pobierając szczegóły inspekcji — wszystko to jest gwarantowane podczas kompilacji.
Wynik powinien pokazywać zarówno format wyświetlania, jak i rezultat inspekcji:
{name} (SN: {serial})
Inspecting: {name}Na przykład dla danych wejściowych Smartwatch i 98765:
Smartwatch (SN: 98765)
Inspecting: SmartwatchOtrzymasz dwa dane wejściowe: nazwę gadżetu i numer seryjny (parsuj jako u32).
Spróbuj swoich sił
mod product;
use product::{Gadget, full_report};
fn main() {
// Wczytaj dane wejściowe
let mut name = String::new();
std::io::stdin().read_line(&mut name).expect("Failed to read line");
let name = name.trim().to_string();
let mut serial_input = String::new();
std::io::stdin().read_line(&mut serial_input).expect("Failed to read line");
let serial: u32 = serial_input.trim().parse().expect("Failed to parse serial");
// TODO: Utwórz instancję Gadget z nazwą i numerem seryjnym
// TODO: Wywołaj full_report, przekazując swój gadżet
}
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