99 lines
2.3 KiB
Rust
99 lines
2.3 KiB
Rust
use std::rc::{Rc, Weak};
|
|
use std::cell::RefCell;
|
|
use List::{Cons, Nil};
|
|
|
|
#[derive(Debug)]
|
|
enum List {
|
|
Cons(i32, RefCell<Rc<List>>),
|
|
Nil,
|
|
}
|
|
|
|
impl List {
|
|
fn tail(&self) -> Option<&RefCell<Rc<List>>> {
|
|
match self {
|
|
Cons(_, item) => Some(item),
|
|
Nil => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
fn cycle_example() {
|
|
let a = Rc::new(Cons(5, RefCell::new(Rc::new(Nil))));
|
|
|
|
println!("a initial rc count = {}", Rc::strong_count(&a));
|
|
println!("a next item = {:?}", a.tail());
|
|
|
|
let b = Rc::new(Cons(10, RefCell::new(Rc::clone(&a))));
|
|
|
|
println!("a rc count after b creation = {}", Rc::strong_count(&a));
|
|
println!("b initial rc count = {}", Rc::strong_count(&b));
|
|
println!("b next item = {:?}", b.tail());
|
|
|
|
if let Some(link) = a.tail() {
|
|
*link.borrow_mut() = Rc::clone(&b);
|
|
}
|
|
|
|
println!("b rc count after changing a = {}", Rc::strong_count(&b));
|
|
println!("a rc count after changing a = {}", Rc::strong_count(&a));
|
|
|
|
// Uncomment the next line to see that we have a cycle;
|
|
// it will overflow the stack
|
|
// println!("a next item = {:?}", a.tail());
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct Node {
|
|
value: i32,
|
|
parent: RefCell<Weak<Node>>,
|
|
children: RefCell<Vec<Rc<Node>>>,
|
|
}
|
|
|
|
fn weakref_example() {
|
|
let leaf = Rc::new(Node {
|
|
value: 3,
|
|
parent: RefCell::new(Weak::new()),
|
|
children: RefCell::new(vec![]),
|
|
});
|
|
|
|
println!(
|
|
"leaf strong = {}, weak = {}",
|
|
Rc::strong_count(&leaf),
|
|
Rc::weak_count(&leaf),
|
|
);
|
|
|
|
{
|
|
let branch = Rc::new(Node {
|
|
value: 5,
|
|
parent: RefCell::new(Weak::new()),
|
|
children: RefCell::new(vec![Rc::clone(&leaf)]),
|
|
});
|
|
|
|
*leaf.parent.borrow_mut() = Rc::downgrade(&branch);
|
|
|
|
println!(
|
|
"branch strong = {}, weak = {}",
|
|
Rc::strong_count(&branch),
|
|
Rc::weak_count(&branch),
|
|
);
|
|
|
|
println!(
|
|
"leaf strong = {}, weak = {}",
|
|
Rc::strong_count(&leaf),
|
|
Rc::weak_count(&leaf),
|
|
);
|
|
}
|
|
|
|
println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());
|
|
println!(
|
|
"leaf strong = {}, weak = {}",
|
|
Rc::strong_count(&leaf),
|
|
Rc::weak_count(&leaf),
|
|
);
|
|
}
|
|
|
|
fn main() {
|
|
cycle_example();
|
|
|
|
weakref_example();
|
|
}
|