study_example/smart_pointer/
reference_cycle.rs1use crate::smart_pointer::reference_cycle::List::{Cons, Nil};
2use std::cell::RefCell;
3use std::rc::{Rc, Weak};
4
5#[derive(Debug)]
6enum List {
7 Cons(i32, RefCell<Rc<List>>),
8 Nil,
9}
10
11impl List {
12 fn tail(&self) -> Option<&RefCell<Rc<List>>> {
13 match self {
14 Cons(_, item) => Some(item),
15 Nil => None,
16 }
17 }
18}
19
20fn create_reference_cycle() {
31 let a = Rc::new(Cons(5, RefCell::new(Rc::new(Nil))));
32 println!("a initial rc count = {}", Rc::strong_count(&a));
33 println!("a next item = {:?}", a.tail());
34 let b = Rc::new(Cons(10, RefCell::new(Rc::clone(&a))));
35 println!("after b create a rc count = {}", Rc::strong_count(&a));
36 println!("b init rc count = {}", Rc::strong_count(&b));
37 println!("b next item = {:?}", b.tail());
38
39 if let Some(link) = a.tail() {
40 *link.borrow_mut() = Rc::clone(&b);
41 }
42 println!("after changing a: b rc count = {}", Rc::strong_count(&b));
43 println!("after changing a: a rc count = {}", Rc::strong_count(&a));
44 }
48
49#[derive(Debug)]
50struct Node {
51 value: i32,
52 parent: RefCell<Weak<Node>>,
53 children: RefCell<Vec<Rc<Node>>>,
54}
55
56fn weak_to_avoid_reference_cycle() {
66 let leaf = Rc::new(Node {
67 value: 3,
68 parent: RefCell::new(Weak::new()),
69 children: RefCell::new(vec![]),
70 });
71 println!(
72 "leaf Rc strong_count = {}, weak = {}",
73 Rc::strong_count(&leaf),
74 Rc::weak_count(&leaf)
75 );
76 println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());
77 {
78 let branch = Rc::new(Node {
79 value: 5,
80 parent: RefCell::new(Weak::new()),
81 children: RefCell::new(vec![Rc::clone(&leaf)]),
82 });
83 *leaf.parent.borrow_mut() = Rc::downgrade(&branch);
84 println!(
85 "baranch strong_count = {}, weak = {}",
86 Rc::strong_count(&branch),
87 Rc::weak_count(&branch)
88 );
89 println!(
90 "leaf after branch Rc strong_count = {}, weak = {}",
91 Rc::strong_count(&leaf),
92 Rc::weak_count(&leaf)
93 );
94 println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());
95 }
96 println!(
97 "leaf after borrow Rc strong_count = {}, weak = {}",
98 Rc::strong_count(&leaf),
99 Rc::weak_count(&leaf)
100 );
101}
102
103pub fn reference_cycle_study() {
104 create_reference_cycle();
105 weak_to_avoid_reference_cycle();
106}