Lecții din modul (2/2)
Trăsături și limite de trăsături
Trăsăturile definesc comportamentul pe care un anumit tip îl are și pe care îl poate împărtăși cu alte tipuri. Putem folosi trăsături pentru a defini un set de metode care reprezintă o anumită funcționalitate sau interfață comună, similară cu interfețele din alte limbaje de programare.
Marginile trăsăturilor ne permit să specificăm că un tip generic trebuie să implementeze o trăsătură specifică, asigurându-se că metodele necesare sunt disponibile în momentul compilării.
Definirea și implementarea unei trăsături
Pentru a defini o trăsătură, folosim cuvântul cheie trait urmat de semnăturile metodelor pe care tipurile de implementare trebuie să le definească:
pub trait Summary {
fn summarize(&self) -> String;
}Pentru a implementa o trăsătură pe un tip concret, folosim sintaxa impl TraitName for TypeName:
pub struct NewsArticle {
pub headline: String,
pub content: String,
}
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{}", self.headline)
}
}Trait Bounds
Când scriem funcții generice, putem constrânge parametrii de tip pentru a ne asigura că implementează o trăsătură specifică. Sintaxa standard este <T: Trait>:
pub fn notify<T: Summary>(item: &T) {
println!("Notification: {}", item.summarize());
}Alternativ, pentru semnături mai complexe, putem folosi clauza where:
pub fn notify_advanced<T>(item: &T)
where
T: Summary
{
println!("Notification: {}", item.summarize());
}Încercați-l singur
Exercițiul 1: Trăsătura rezumată
Definiți o trăsătură numită Summary care conține semnătura metodei fn summarize(&self) -> String;. Apoi, definiți un struct NewsArticle cu un câmp de titlu de tip String și implementați trăsătura Summary pentru acesta, astfel încât metoda summarize să returneze valoarea câmpului de titlu.
Afișează indiciu
Definiți trăsătura `Rezumat` și structura`NewsArticle`. Implementați cu`impl Rezumat pentru NewsArticle`clonarea câmpului`self.headline.clone()`.
Soluție disponibilă după 3 încercări
Exercițiul 2: Trait Bounds cu print_summary
Pe baza codului din exercițiul anterior, definiți o funcție generică numită print_summary<T> care acceptă un parametru de tip &T. Aplicați o trăsătură legată, astfel încât T trebuie să implementeze trăsătura Rezumat. În interiorul funcției, imprimați rezultatul returnat de item.summarize().
Afișează indiciu
Folosiți semnătura `fn print_summary<T: Summary>(item: &T)`și invocați`item.summarize()`în interiorul`println!`.
Soluție disponibilă după 3 încercări
Exercițiul 3: Calculul suprafeței folosind trăsături
Definiți o trăsătură numită Area cu metoda fn area(&self) -> f64;. Creați o structură Cerc care conține un câmp de rază de tip f64 și implementați trăsătura Arie pentru acesta calculând zona (formula: rază * rază * 3,14159).
Afișează indiciu
Definiți trăsătura `Area` și structura`Circle. Implementați `area(&self)` folosind formula zonei cercului.
Soluție disponibilă după 3 încercări