Weak references break cycles in Rust
A child pointing back at its parent must do so weakly, or nothing is ever freed.
use std::cell::RefCell;
use std::rc::{Rc, Weak};
struct Node {
name: String,
parent: RefCell<Weak<Node>>,
children: RefCell<Vec<Rc<Node>>>,
}
fn main() {
let root = Rc::new(Node {
name: "tours".to_string(),
parent: RefCell::new(Weak::new()),
children: RefCell::new(Vec::new()),
});
let leaf = Rc::new(Node {
name: "basics".to_string(),
parent: RefCell::new(Rc::downgrade(&root)),
children: RefCell::new(Vec::new()),
});
root.children.borrow_mut().push(Rc::clone(&leaf));
if let Some(parent) = leaf.parent.borrow().upgrade() {
println!("{} is under {}", leaf.name, parent.name);
}
println!("strong {} weak {}", Rc::strong_count(&root),
Rc::weak_count(&root));
}
How it works
Rc::downgrademakes a non-owningWeakhandle.upgradereturnsNoneonce the target is gone.- Two strong references in a cycle leak the whole cycle.
Keywords and builtins used here
NodeRefCellSomeStringVecfnifletmainstructuse
The run, in numbers
- Lines
- 30
- Characters to type
- 665
- Tokens
- 231
- Three-star pace
- 110 tpm
At the three-star pace of 110 tokens a minute, this run takes about 126 seconds.
Step 3 of 3 in Interior mutability, step 9 of 11 in Lifetimes & interior mutability.