mem::drop în Rust

Distruge o valoare imediat, înainte de sfârșitul blocului: eliberează memoria, închide fișierul, deblochează mutex-ul.

Sintaxă
pub fn drop<T>(_x: T)

Ce face mem::drop

Rust distruge automat fiecare valoare când proprietarul ei iese din domeniu. drop(x) îți permite să faci asta mai devreme: funcția primește valoarea (o mută) și nu face nimic cu ea, așa că valoarea este distrusă la finalul apelului, iar codul din Drop rulează atunci.

Cazuri tipice: eliberezi un MutexGuard ca să permiți altor fire accesul, închizi un fișier sau un Sender, termini un împrumut RefCell. drop este în prelude, deci nu ai nevoie de use std::mem. Nu poți apela direct metoda x.drop().

Parametri

Parametru Descriere
_x Valoarea distrusă.

Ce returnează

Nimic.

Exemple

Exemplul 1: Ordinea distrugerii

Fără drop, valorile sunt distruse la sfârșitul lui main, în ordinea inversă creării. drop(a) o distruge pe a imediat.

struct Conexiune(&'static str);

impl Drop for Conexiune {
    fn drop(&mut self) {
        println!("închid conexiunea {}", self.0);
    }
}

fn main() {
    let a = Conexiune("Iași");
    let _b = Conexiune("Cluj");
    let _c = Conexiune("Timișoara");

    drop(a);
    println!("lucrez în continuare...");
    println!("sfârșitul lui main");
}

Rezultat

închid conexiunea Iași
lucrez în continuare...
sfârșitul lui main
închid conexiunea Timișoara
închid conexiunea Cluj

Exemplul 2: Eliberarea unui lacăt

După drop(g), mutex-ul este liber și try_lock reușește.

use std::sync::Mutex;

fn main() {
    let stoc = Mutex::new(10);

    let mut g = stoc.lock().unwrap();
    *g -= 3;
    println!("liber în timp ce țin lock-ul: {}", stoc.try_lock().is_ok());
    drop(g);
    println!("liber după drop: {}", stoc.try_lock().is_ok());
    println!("stoc: {}", stoc.lock().unwrap());
}

Rezultat

liber în timp ce țin lock-ul: false
liber după drop: true
stoc: 7

Greșeli frecvente

  • Apelezi drop(x) pe o valoare Copy (un număr, o referință &T): se distruge doar o copie, originalul rămâne. Pentru referințe, avertismentul dropping_references te anunță.
  • Scrii x.drop(): compilatorul refuză apelul explicit al destructorului (eroarea E0040). Folosește drop(x).
  • Folosești let _ = valoare; crezând că o păstrezi: _ nu leagă nimic, deci o valoare temporară este distrusă imediat. Pentru a o păstra, dă-i un nume ca _g.

Comenzi înrudite

  • Mutex::lock: Obține accesul exclusiv la valoarea din Mutex, așteptând dacă alt fir o folosește; returnează un guard.
  • RefCell::borrow: borrow() împrumută valoarea din RefCell pentru citire, borrow_mut() pentru scriere; conflictele dau panică.
  • mpsc::channel: Creează un canal prin care firele își trimit mesaje: Sender trimite cu send(), Receiver primește.
  • mem::take: Mută valoarea afară dintr-un loc mutabil și lasă în loc valoarea implicită a tipului (text gol, vector gol, 0).