typestar

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

  1. Rc::downgrade makes a non-owning Weak handle.
  2. upgrade returns None once the target is gone.
  3. Two strong references in a cycle leak the whole cycle.

Keywords and builtins used here

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.

Type this snippet

Step 3 of 3 in Interior mutability, step 9 of 11 in Lifetimes & interior mutability.

← Previous Next →