capypad
0 Tage Serie
rust / intermediate
Snippet

Innere Veränderlichkeit mit Cell und RefCell

Innere Veränderlichkeit ermöglicht die Mutation von Daten durch eine gemeinsame Referenz. Cell<T> bietet Mutation für Copy-Typen, während RefCell<T> eine Laufzeit-Ausleiheprüfung für Non-Copy-Typen bietet. In diesem Beispiel verwendet Counter Cell für den Zahlenwert und RefCell für den Verlaufsvektor, was Mutation auch mit &self-Referenzen ermöglicht. Der Ausleihprüfer stellt sicher, dass nur eine veränderliche Referenz oder mehrere unveränderliche Referenzen gleichzeitig existieren können.

snippet.rs
rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
use std::cell::{Cell, RefCell};
 
struct Counter {
value: Cell<u32>,
history: RefCell<Vec<u32>>,
}
 
impl Counter {
fn new() -> Self {
Counter {
value: Cell::new(0),
history: RefCell::new(Vec::new()),
}
}
 
fn increment(&self) {
let new_val = self.value.get() + 1;
self.value.set(new_val);
self.history.borrow_mut().push(new_val);
}
 
fn get_value(&self) -> u32 {
self.value.get()
}
 
fn get_history(&self) -> Vec<u32> {
self.history.borrow().clone()
}
}
 
fn main() {
let counter = Counter::new();
counter.increment();
counter.increment();
counter.increment();
println!("Value: {}", counter.get_value());
println!("History: {:?}", counter.get_history());
}
Erklärung
1
use std::cell::{Cell, RefCell};
Importiert Cell für Copy-Typen und RefCell für Laufzeit-Ausleiheprüfung
2
value: Cell<u32>,
Cell umschließt Copy-Typen und ermöglicht interne Mutation ohne &mut self
3
history: RefCell<Vec<u32>>,
RefCell umschließt Non-Copy-Typen mit Laufzeit-Ausleiheprüfung
4
self.value.get()
Kopiert den Wert atomar aus der Cell
5
self.history.borrow_mut().push(new_val);
borrow_mut gibt eine RefMut-Wächter zurück; Panic bei bereits vorhandener Ausleihe