% Distruzione ["Drop"]
Adesso che abbiamo parlato dei tratti, parliamo di un particolare tratto
fornito dalla libreria standard di Rust, Drop
, che letteralmente
significa "lasciar cadere", ma qui va inteso nel senso di "distruggere".
Il tratto Drop
svolge la funzione che in altri linguaggi di programmazione
è svolta dai "distruttori"; infatti fornisce un modo di eseguire del codice
quando un oggetto esce dal suo ambito.
Per esempio:
struct DaDistruggere;
impl Drop for DaDistruggere {
fn drop(&mut self) {
println!("Distruzione!");
}
}
fn main() {
let x = DaDistruggere;
// fai qualcosa
} // qui x esce di ambito e stampa "Distruzione!"
Quando x
esce di ambito, alla fine della funzione main()
, il metodo
drop
verrà eseguito. Tale metodo, che è l'unico di Drop
, prende
un riferimento mutabile a self
.
Ecco fatto! La meccanica di Drop
è molto semplice, ma ci sono alcune
sottigliezze. Per esempio, i valori vengono distrutti nell'ordine opposto
a quello in cui sono stati dichiarati. Ecco un altro esempio:
struct Esplosivo {
energia: i32,
}
impl Drop for Esplosivo {
fn drop(&mut self) {
println!("BUM per {}!", self.energia);
}
}
fn main() {
let petardo = Esplosivo { energia: 1 };
let granata = Esplosivo { energia: 100 };
let bomba = Esplosivo { energia: 1000 };
}
Questo programma stamperà:
BUM per 1000!
BUM per 100!
BUM per 1!
La bomba
esplode prima della granata
, che esplode prima del petardo
,
perché sono stati dichiarati in quell'ordine invertito.
Ultimo dentro, primo fuori.
Dunque a cosa serve il tratto Drop
? In generale, Drop
viene usato
per distruggere le risorse associate a una struct
. Per esempio,
Arc<T>
è un tipo che contiene un oggetto di tipo generico T
e
un conteggio di riferimenti. Quando viene chiamato il suo metodo drop
,
questo metodo decrementa il conteggio dei riferimenti,
e se tale conteggio è diventato zero, dealloca l'oggetto contenuto.