Przejdź do głównej treści
eLearner.app
Moduł 5 · Lekcja 2 z 210/14 w kursie~15 min
Lekcje modułu (2/2)

Cechy i ograniczenia (Traits / Trait Bounds)

Traity definiują zachowanie, które posiada konkretny typ i które może być współdzielone z innymi typami. Możemy używać traitów do zdefiniowania zestawu metod reprezentujących określoną wspólną funkcjonalność lub interfejs, podobnie jak interfejsy w innych językach programowania.

Trait bounds (ograniczenia traitu) pozwalają określić, że typ ogólny (generyczny) musi implementować dany trait, gwarantując, że wymagane metody będą dostępne w czasie kompilacji.


Definiowanie i implementowanie traitu

Aby zdefiniować trait, używamy słowa kluczowego trait wraz z sygnaturami metod, które typy muszą zaimplementować:

Code
pub trait Summary {
    fn summarize(&self) -> String;
}

Aby zaimplementować trait dla konkretnego typu, używamy składni impl TraitName for TypeName:

Code
pub struct NewsArticle {
    pub headline: String,
    pub content: String,
}

impl Summary for NewsArticle {
    fn summarize(&self) -> String {
        format!("{}", self.headline)
    }
}

Trait Bounds (Ograniczenia Traitu)

Kiedy piszemy funkcje generyczne, możemy ograniczyć parametry typu, aby upewnić się, że implementują one określony trait. Standardowa składnia to <T: Trait>:

Code
pub fn notify<T: Summary>(item: &T) {
    println!("Notifica: {}", item.summarize());
}

Alternatywnie, dla bardziej skomplikowanych sygnatur, możemy użyć klauzuli where:

Code
pub fn notify_advanced<T>(item: &T)
where
    T: Summary
{
    println!("Notifica: {}", item.summarize());
}

Spróbuj sam

Ćwiczenie 1: Trait Summary

Ćwiczenie#rust.m5.l2.e1
Próby: 0Ładowanie...

Zdefiniuj trait o nazwie Summary zawierający sygnaturę metody fn summarize(&self) -> String;. Następnie zdefiniuj strukturę (struct) NewsArticle z polem headline typu String i zaimplementuj dla niej trait Summary tak, aby metoda summarize zwracała wartość pola headline.

Ładowanie edytora...
Pokaż wskazówkę

Zdefiniuj trait `Summary`i strukturę`NewsArticle`. Zaimplementuj za pomocą `impl Summary for NewsArticle`klonując pole`self.headline.clone()`.

Rozwiązanie dostępne po 3 próbach

Ćwiczenie 2: Trait Bounds z print_summary

Ćwiczenie#rust.m5.l2.e2
Próby: 0Ładowanie...

Opierając się na kodzie z poprzedniego ćwiczenia, zdefiniuj funkcję generyczną o nazwie print_summary<T>, która przyjmuje parametr item typu &T. Zastosuj ograniczenie (trait bound) tak, aby T musiało implementować trait Summary. Wewnątrz funkcji wypisz na ekranie wynik zwrócony przez item.summarize().

Ładowanie edytora...
Pokaż wskazówkę

Użyj sygnatury `fn print_summary<T: Summary>(item: &T)`i wywołaj`item.summarize()`wewnątrz`println!`.

Rozwiązanie dostępne po 3 próbach

Ćwiczenie 3: Obliczanie pola powierzchni za pomocą Traitu

Ćwiczenie#rust.m5.l2.e3
Próby: 0Ładowanie...

Zdefiniuj trait o nazwie Area z metodą fn area(&self) -> f64;. Utwórz strukturę Circle zawierającą pole radius typu f64 i zaimplementuj dla niej trait Area, obliczając pole powierzchni (wzór: radius * radius * 3.14159).

Ładowanie edytora...
Pokaż wskazówkę

Zdefiniuj trait `Area`i strukturę`Circle`. Zaimplementuj `area(&self)` przy użyciu wzoru na pole koła.

Rozwiązanie dostępne po 3 próbach