Ce face LazyLock
LazyLock::new(f) ține funcția f și o rulează abia la prima accesare a valorii. Spre deosebire de OnceLock, nu mai chemi get_or_init: folosești statica direct, ca pe valoarea însăși (MAP.get("x"), *NUMAR), iar inițializarea se face singură.
Este înlocuitorul standard al crate-ului lazy_static și al lui once_cell::sync::Lazy. Pentru o variantă fără sincronizare, folosită într-un singur fir, există std::cell::LazyCell.
Parametri
| Parametru | Descriere |
|---|---|
f |
Funcția (de obicei un closure fără captură) care creează valoarea. |
Ce returnează
Un LazyLock<T> care se folosește ca &T.
Exemple
Exemplul 1: Tabel global creat la prima folosire
Mesajul de inițializare apare abia la prima căutare, nu la pornirea programului.
use std::collections::BTreeMap;
use std::sync::LazyLock;
static JUDETE: LazyLock<BTreeMap<&str, &str>> = LazyLock::new(|| {
println!("(construiesc tabelul de județe)");
BTreeMap::from([("IS", "Iași"), ("CJ", "Cluj"), ("BV", "Brașov")])
});
fn main() {
println!("pornesc programul");
println!("IS = {:?}", JUDETE.get("IS"));
println!("CJ = {:?}", JUDETE.get("CJ"));
println!("XX = {:?}", JUDETE.get("XX"));
println!("{} județe", JUDETE.len());
}
Rezultat
pornesc programul
(construiesc tabelul de județe)
IS = Some("Iași")
CJ = Some("Cluj")
XX = None
3 județe
Exemplul 2: O valoare calculată, folosită din mai multe fire
use std::sync::LazyLock;
use std::thread;
static PRIME: LazyLock<Vec<u32>> = LazyLock::new(|| {
(2..50).filter(|n| (2..*n).all(|d| n % d != 0)).collect()
});
fn main() {
let numere = [7, 21, 47];
let raspunsuri: Vec<String> = thread::scope(|s| {
let fire: Vec<_> = numere
.iter()
.map(|n| s.spawn(move || format!("{n} este prim: {}", PRIME.contains(n))))
.collect();
fire.into_iter().map(|f| f.join().unwrap()).collect()
});
for r in raspunsuri {
println!("{r}");
}
println!("prime sub 50: {}", PRIME.len());
}
Rezultat
7 este prim: true
21 este prim: false
47 este prim: true
prime sub 50: 15
Greșeli frecvente
- Te aștepți ca valoarea să fie creată la pornire: este creată abia la prima accesare. Dacă vrei verificarea erorilor la pornire, accesează statica explicit la începutul lui
main. - Funcția de inițializare intră în panică:
LazyLockdevine otrăvit, iar orice accesare ulterioară intră și ea în panică.
Comenzi înrudite
OnceLock: Celulă care primește o valoare o singură dată, sigur între fire; ideală pentru valori globale calculate la prima folosire.Mutex: Protejează o valoare folosită din mai multe fire: lock() așteaptă până când firul curent este singurul cu acces.Box::leak: Renunță la un Box fără să elibereze memoria și dă o referință valabilă până la finalul programului (&’static).