Ce face RefCell::borrow
borrow() returnează un Ref<T>, care se comportă ca &T. Pot exista oricâte Ref-uri în același timp. borrow_mut() returnează un RefMut<T>, care se comportă ca &mut T; poate exista doar unul și niciun Ref în paralel.
RefCell ține un contor al împrumuturilor active. Când variabila Ref/RefMut dispare (la sfârșitul blocului sau al expresiei), contorul scade. Un apel care ar încălca regula intră în panică cu RefCell already borrowed sau RefCell already mutably borrowed.
Ce returnează
Ref<'_, T>, respectiv RefMut<'_, T>.
Exemple
Exemplul 1: Mai mulți cititori în același timp
use std::cell::RefCell;
fn main() {
let oras = RefCell::new(String::from("Iași"));
let a = oras.borrow();
let b = oras.borrow();
println!("a = {a}, b = {b}, lungime = {}", a.len());
drop(a);
drop(b);
oras.borrow_mut().push_str(" (capitala Moldovei)");
println!("{}", oras.borrow());
}
Rezultat
a = Iași, b = Iași, lungime = 5
Iași (capitala Moldovei)
Exemplul 2: Panica la două împrumuturi de scriere
primul ține împrumutul de scriere până la finalul lui main, așa că al doilea borrow_mut intră în panică.
use std::cell::RefCell;
fn main() {
let scor = RefCell::new(0);
let mut primul = scor.borrow_mut();
let mut al_doilea = scor.borrow_mut();
*primul += 1;
*al_doilea += 1;
}
Rezultat (programul se oprește cu panică, codul de ieșire 101)
thread 'main' (61277) panicked at src/main.rs:6:30:
RefCell already borrowed
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Greșeli frecvente
- Scrii
let v = celula.borrow_mut(); functie(&celula);, iarfunctiefaceborrow(): panică. Eliberează împrumutul înainte de apel. - Folosești
if letsaumatchpecelula.borrow()și modifici celula în ramuri: împrumutul ține pe toată durata construcției.
Comenzi înrudite
RefCell: Permite modificarea unei valori prin referință comună (&), verificând regulile de împrumut la rulare, nu la compilare.Cell: Celulă cu mutabilitate interioară pentru valori Copy: get() copiază valoarea afară, set() pune una nouă, prin &self.mem::drop: Distruge o valoare imediat, înainte de sfârșitul blocului: eliberează memoria, închide fișierul, deblochează mutex-ul.