Drop în Rust

Codul rulat automat când o valoare iese din domeniu (destructor): închidere de fișiere, eliberare de resurse, mesaje.

Sintaxă
impl Drop for Tip {
    fn drop(&mut self) { ... }
}

Ce face Drop

Când o variabilă iese din domeniu (la acolada de închidere), Rust îi apelează automat drop. Pentru majoritatea tipurilor nu scrii nimic: String, Vec, File își eliberează singure resursele. Implementezi Drop când tipul tău trebuie să facă ceva la final: să închidă o conexiune, să scrie un jurnal, să elibereze un blocaj.

Variabilele locale sunt distruse în ordine inversă declarării; câmpurile unei structuri, în ordinea declarării, după drop-ul structurii. Nu poți apela direct x.drop(); ca să distrugi o valoare mai devreme, folosește drop(x) (funcția std::mem::drop, din preludiu), care o mută și o eliberează imediat.

Un tip cu Drop nu poate fi Copy.

Parametri

Parametru Descriere
drop(&mut self) Singura metodă; nu returnează nimic și nu poate fi apelată direct.

Ce returnează

Nimic.

Exemple

Exemplul 1: Ordinea distrugerii

struct Resursa {
    nume: &'static str,
}

impl Drop for Resursa {
    fn drop(&mut self) {
        println!("eliberez {}", self.nume);
    }
}

fn main() {
    let _a = Resursa { nume: "conexiunea la baza de date" };
    let _b = Resursa { nume: "fișierul jurnal" };
    {
        let _c = Resursa { nume: "blocul interior" };
        println!("sfârșitul blocului interior");
    }
    println!("sfârșitul lui main");
}

Rezultat

sfârșitul blocului interior
eliberez blocul interior
sfârșitul lui main
eliberez fișierul jurnal
eliberez conexiunea la baza de date

Exemplul 2: Eliberare mai devreme cu drop()

struct Blocaj {
    resursa: String,
}

impl Drop for Blocaj {
    fn drop(&mut self) {
        println!("deblochez {}", self.resursa);
    }
}

fn main() {
    let b = Blocaj { resursa: String::from("contul #42") };
    println!("lucrez cu {}", b.resursa);
    drop(b);                               // deblocare imediată
    println!("continui fără blocaj");
}

Rezultat

lucrez cu contul #42
deblochez contul #42
continui fără blocaj

Greșeli frecvente

  • Apelezi x.drop(): explicit use of destructor method. Folosește drop(x).
  • Scrii let _ = Resursa { ... }; crezând că valoarea trăiește până la final. Cu _ simplu, valoarea este distrusă imediat; cu _nume, trăiește până la sfârșitul blocului.

Comenzi înrudite

  • Copy: Trait marker pentru tipurile copiate automat bit cu bit la atribuire, în loc să fie mutate (numere, char, bool…).
  • Deref: Trait-ul din spatele operatorului * și al conversiei automate &Box<T> -> &T, &String -> &str (deref coercion).
  • Clone: Trait-ul pentru copierea explicită a unei valori cu .clone(); se obține cu #[derive(Clone)] sau implementare manuală.