Ce face Cell
Cell<T> permite schimbarea valorii prin referință comună, ca și RefCell, dar fără împrumuturi: nu primești niciodată o referință spre interior. get() returnează o copie a valorii (deci T trebuie să fie Copy), iar set(v) înlocuiește valoarea.
Pentru că nu există împrumuturi, Cell nu poate intra în panică și nu are cost la rulare. Este potrivit pentru contoare, indicatori bool sau valori mici într-o structură folosită prin &self. Pentru tipuri care nu sunt Copy există take() și replace(). Ca și RefCell, nu poate fi împărțit între fire.
Parametri
| Parametru | Descriere |
|---|---|
value |
Valoarea inițială (la new). |
val |
Noua valoare (la set). |
Ce returnează
get: o copie a valorii. set: nimic.
Exemple
Exemplul 1: Contor de vizite prin &self
use std::cell::Cell;
struct Pagina {
titlu: &'static str,
vizite: Cell<u32>,
}
impl Pagina {
fn deschide(&self) {
self.vizite.set(self.vizite.get() + 1);
}
}
fn main() {
let p = Pagina { titlu: "Option în Rust", vizite: Cell::new(0) };
for _ in 0..3 {
p.deschide();
}
println!("{}: {} vizite", p.titlu, p.vizite.get());
}
Rezultat
Option în Rust: 3 vizite
Exemplul 2: Indicator comun pentru mai multe closure-uri
Ambele closure-uri împrumută celula prin &, lucru care nu ar fi posibil cu un bool obișnuit modificat în ele.
use std::cell::Cell;
fn main() {
let salvat = Cell::new(true);
let modifica = || salvat.set(false);
let salveaza = || salvat.set(true);
println!("la început: {}", salvat.get());
modifica();
println!("după modificare: {}", salvat.get());
salveaza();
println!("după salvare: {}", salvat.get());
let nume = Cell::new(String::from("Ana"));
let vechi = nume.replace(String::from("Ioana"));
println!("vechi = {vechi}, nou = {}", nume.take());
}
Rezultat
la început: true
după modificare: false
după salvare: true
vechi = Ana, nou = Ioana
Greșeli frecvente
- Apelezi
get()pe unCell<String>: nu compilează, pentru căStringnu esteCopy. Foloseștetake()/replace()sauRefCell. - Folosești
Cellîntre fire: nu esteSync. Pentru un contor comun foloseșteAtomicUsize.
Comenzi înrudite
RefCell: Permite modificarea unei valori prin referință comună (&), verificând regulile de împrumut la rulare, nu la compilare.AtomicUsize: Număr întreg care poate fi citit și modificat din mai multe fire fără Mutex, cu operații atomice.mem::replace: Pune o valoare nouă într-un loc mutabil și returnează valoarea veche, mutată afară.