Da std::cell
documentation, vedo che Cell
è "compatibile solo con i tipi che implementano Copy
". Ciò significa che è necessario utilizzare RefCell
per i tipi non Copy
.Quando posso usare Cell o RefCell, quale dovrei scegliere?
Quando I do ha un tipo Copy
, c'è un vantaggio nell'usare un tipo di cella rispetto a un altro? Presumo che la risposta sia "sì", perché altrimenti non esisterebbero entrambi i tipi! Quali sono i vantaggi e gli svantaggi dell'utilizzo di un tipo rispetto all'altro?
Ecco un stupido esempio, made-up che utilizza sia Cell
e RefCell
per raggiungere lo stesso obiettivo:
use std::cell::{Cell,RefCell};
struct ThingWithCell {
counter: Cell<u8>,
}
impl ThingWithCell {
fn new() -> ThingWithCell {
ThingWithCell { counter: Cell::new(0) }
}
fn increment(&self) {
self.counter.set(self.counter.get() + 1);
}
fn count(&self) -> u8 { self.counter.get() }
}
struct ThingWithRefCell {
counter: RefCell<u8>,
}
impl ThingWithRefCell {
fn new() -> ThingWithRefCell {
ThingWithRefCell { counter: RefCell::new(0) }
}
fn increment(&self) {
let mut counter = self.counter.borrow_mut();
*counter = *counter + 1;
}
fn count(&self) -> u8 { *self.counter.borrow_mut() }
}
fn main() {
let cell = ThingWithCell::new();
cell.increment();
println!("{}", cell.count());
let cell = ThingWithRefCell::new();
cell.increment();
println!("{}", cell.count());
}
È possibile ottenere la semantica del valore con 'RefCell': clonare lo stato iniziale, lavorarci sopra e riscrivere lo stato modificato nella cella alla fine. –
@MatthieuM. ma non puoi ottenere la semantica di riferimento con 'Cell', corretto? – Shepmaster
@Shepmaster: Beh, puoi avere riferimenti a 'Cell'. Se vuoi un riferimento al valore puoi usare il suo componente 'UnsafeCell', e' UnsafeCell' può darti un puntatore al valore di riferimento ... ma non è sicuro (come per il nome). Quindi, no, 'Cell' non è pensato per manipolare i riferimenti; non sarebbe al sicuro altrimenti, come si rompe dai controlli di prestito. –