Ce face Deref
Deref spune ce se obține când „urmezi” o valoare ca pe un pointer: *x. Îl implementează pointerii inteligenți (Box, Rc, Arc), dar și String (spre str) și Vec<T> (spre [T]).
Efectul cel mai util este deref coercion: când o funcție cere &str și îi dai &String, Rust aplică automat deref. La fel, metodele lui str se pot apela pe un String, iar metodele lui T pe un Box<T>. Pentru acces mutabil există perechea DerefMut.
Implementează Deref pentru tipuri „înveliș” (newtype, pointeri proprii), nu ca să imiți moștenirea din alte limbaje: codul devine greu de urmărit.
Parametri
| Parametru | Descriere |
|---|---|
type Target |
Tipul spre care „arată” valoarea. |
deref(&self) |
Returnează referința spre Target. |
Ce returnează
&Self::Target.
Exemple
Exemplul 1: Un newtype care se folosește ca &str
use std::ops::Deref;
struct NumeOras(String);
impl Deref for NumeOras {
type Target = str;
fn deref(&self) -> &str {
&self.0
}
}
fn salut(oras: &str) {
println!("Bun venit în {oras}!");
}
fn main() {
let o = NumeOras(String::from("Suceava"));
salut(&o); // &NumeOras -> &str automat
println!("{} litere, majuscule: {}", o.chars().count(), o.to_uppercase());
println!("începe cu S: {}", o.starts_with('S'));
}
Rezultat
Bun venit în Suceava!
7 litere, majuscule: SUCEAVA
începe cu S: true
Exemplul 2: Operatorul * și Box
fn main() {
let x = 5;
let r = &x;
let b = Box::new(10);
println!("{} {}", *r + 1, *b + 1);
let text: Box<String> = Box::new(String::from("Galați"));
let felie: &str = &text; // Box<String> -> String -> str
println!("{felie} are {} octeți", text.len());
}
Rezultat
6 11
Galați are 7 octeți
Greșeli frecvente
- Folosești
Derefca să „moștenești” metodele unui tip în altul (Caine→Animal). Rust recomandă compoziția și trait-urile pentru asta. - Uiți că
derefreturnează o referință, nu o valoare:let s: String = *text;pe un&Stringîncearcă să mute valoarea și nu compilează.
Comenzi înrudite
AsRef: Conversie ieftină de la referință la referință; folosit în funcții generice care acceptă String, &str, PathBuf etc.Drop: Codul rulat automat când o valoare iese din domeniu (destructor): închidere de fișiere, eliberare de resurse, mesaje.String::as_str: Returnează un &str care împrumută tot conținutul String-ului; util la match și unde se cere explicit &str.Sized: Trait marker pentru tipurile cu dimensiune cunoscută la compilare; ?Sized permite și str, [T], dyn Trait.