Box::leak în Rust

Renunță la un Box fără să elibereze memoria și dă o referință valabilă până la finalul programului (&'static).

Sintaxă
fn leak<'a>(b: Box<T>) -> &'a mut T

Ce face Box::leak

Box::leak(b) consumă box-ul, dar nu eliberează memoria. În schimb îți dă o referință &mut T cu orice durată de viață, inclusiv 'static. Valoarea trăiește până la finalul programului.

Se folosește pentru date create o singură dată la pornire (configurare citită din fișier, un text construit la rulare) care trebuie să fie &'static, de exemplu ca să fie folosite din fire sau în structuri care cer 'static. Se apelează Box::leak(b), nu b.leak().

Parametri

Parametru Descriere
b Box-ul la care renunți.

Ce returnează

&'a mut T, care poate fi folosit ca &'static T.

Exemple

Exemplul 1: Un text construit la rulare, folosit ca &’static str

into_boxed_str() transformă String-ul în Box<str>, iar leak dă un &'static str. Firul are voie să-l folosească: move copiază doar referința, iar textul rămâne disponibil și în main.

use std::thread;

fn main() {
    let nume_site = format!("{}.{}", "dexblog", "ro");
    let static_nume: &'static str = Box::leak(nume_site.into_boxed_str());

    let fir = thread::spawn(move || format!("Salut de pe {static_nume}!"));
    println!("{}", fir.join().unwrap());
    println!("Tot aici: {static_nume}");
}

Rezultat

Salut de pe dexblog.ro!
Tot aici: dexblog.ro

Exemplul 2: Configurare globală creată o singură dată

struct Config {
    oras: String,
    limba: &'static str,
}

fn incarca_config() -> &'static Config {
    let c = Box::new(Config { oras: String::from("Cluj"), limba: "ro" });
    Box::leak(c)
}

fn main() {
    let config = incarca_config();
    println!("oraș = {}, limbă = {}", config.oras, config.limba);
}

Rezultat

oraș = Cluj, limbă = ro

Greșeli frecvente

  • Apelezi Box::leak într-o buclă: fiecare apel pierde memorie pentru totdeauna, iar programul crește continuu.
  • Pentru o valoare globală creată la prima folosire, OnceLock sau LazyLock sunt de obicei mai clare decât leak.

Comenzi înrudite

  • Box: Pune o valoare în memoria heap și o deține; folosit pentru tipuri recursive și pentru Box<dyn Trait>.
  • OnceLock: Celulă care primește o valoare o singură dată, sigur între fire; ideală pentru valori globale calculate la prima folosire.
  • LazyLock: Valoare calculată automat la prima folosire, sigur între fire; se folosește ca static global.