rust / intermediate
Snippet
Zyklische Smart Pointer mit Rc und RefCell
Rc (Reference Counting) ermöglicht Mehrfachbesitz, aber Zyklen verursachen Speicherlecks. Schwache Referenzen (Weak) brechen Zyklen - eine Weak erhöht den strong count nicht. Die upgrade()-Methode konvertiert Weak zurück zu Option<Rc>. In dieser Baumstruktur hält parent eine Weak-Referenz, um Kinder nicht zu behalten, während Kinder starke Rc-Referenzen zu ihrem Parent halten. Rc::downgrade erstellt eine Weak aus einer Rc, und der Ausleihprüfer stellt sicher, dass keine Referenzzyklen zur Kompilierzeit existieren.
snippet.rs
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::RefCell;use std::rc::{Rc, Weak};#[derive(Debug)]struct Node {value: i32,children: RefCell<Vec<Rc<Node>>>,parent: RefCell<Weak<Node>>,}impl Node {fn new(value: i32) -> Rc<Self> {Rc::new(Node {value,children: RefCell::new(Vec::new()),parent: RefCell::new(Weak::new()),})}fn add_child(&self, child: Rc<Node>) {self.children.borrow_mut().push(Rc::clone(&child));*child.parent.borrow_mut() = Rc::downgrade(self);}fn get_parent(&self) -> Option<Rc<Node>> {self.parent.borrow().upgrade()}}fn main() {let leaf = Node::new(3);let branch = Node::new(5);branch.add_child(Rc::clone(&leaf));println!("Leaf parent: {:?}", leaf.get_parent());println!("Branch strong count: {}", Rc::strong_count(&branch));println!("Leaf strong count: {}", Rc::strong_count(&leaf));}
Erklärung
1
parent: RefCell<Weak<Node>>
Weak verhindert nicht, dass Node verworfen wird; verhindert starke Zyklen
2
Rc::downgrade(self)
Erstellt einen Weak-Zeiger auf Rc; erhöht Referenzcount nicht
3
child.parent.borrow_mut() = Rc::downgrade(self);
Setzt die schwache Parent-Referenz des Kindes auf diesen Knoten
4
self.parent.borrow().upgrade()
Konvertiert Weak zu Option<Rc>; None wenn Parent verworfen wurde