-
-
Save piboistudios/c8db0e9b25efbcd5fa22c53e3db89780 to your computer and use it in GitHub Desktop.
[RUST]Parent-Children Tree (#2)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// we will use weak references with the Rc<T> (reference counting pointer) type | |
// weak references allow us to make references to a value that will -not- keep it alive | |
// this is perfect in the intsance of children, as we will soon see | |
use std::rc::{Rc,Weak}; | |
use std::cell::RefCell; | |
// this example builds upon the last by storing a vector of children as well as a parent | |
#[derive(Debug)] | |
struct Node { | |
value: i32, | |
// you may ask why exactly we are mutating immutable data as opposed to just using &Weak<Node> | |
// the answer is lifetimes :) | |
parent: RefCell<Weak<Node>>, | |
children: RefCell<Vec<Rc<Node>>>, | |
} | |
fn main() { | |
// lets create the child first | |
let leaf = Rc::new(Node { | |
value: 3, | |
// recall that we must use associated functions to get the appropriate pointer types | |
children: RefCell::new(vec![]), | |
// even the Weak pointer has an associated new() fn | |
parent: RefCell::new(Weak::new()), | |
}); | |
println!( // print out the strong and weak reference counts for the leaf, they should equal 1 and 0 | |
"leaf strong = {} weak = {}", | |
Rc::strong_count(&leaf), | |
Rc::weak_count(&leaf) | |
); | |
{ // create a new scope within our main function | |
let branch = Rc::new(Node{ // create a branch where the previously created leaf is our child | |
value:5, | |
children: RefCell::new(vec![Rc::clone(&leaf)]), | |
parent: RefCell::new(Weak::new()), | |
}); | |
// 1. borrow a mutable reference of the leaf's parent | |
// 2. dereference it | |
// 3. set it equal to a weak reference to the branch node | |
*leaf.parent.borrow_mut() = Rc::downgrade(&branch); | |
println!(// print branch ref counts | |
"branch strong = {} weak = {}", | |
Rc::strong_count(&branch), | |
Rc::weak_count(&branch), | |
); | |
println!( // print leaf ref counts | |
"leaf strong = {} weak = {}", | |
Rc::strong_count(&leaf), | |
Rc::weak_count(&leaf) | |
); | |
// we can tell that weak referencing works because this actually can print out the parent | |
// whereas before when we tried printing an object(1) with a reference to an object(2) that holds a reference to | |
// the original object(1) (recall this is what we did in the Cons-List exercise | |
println!("leaf parent = {:#?}", leaf.parent.borrow().upgrade()); | |
} // parent goes out of scope even though the child has a reference to it | |
// the parent now equals None! it's gone out of scope even though we had a reference to it! | |
// println!("leaf parent = {:#?}", leaf.parent.borrow().upgrade()); | |
println!( // print ref counts | |
"leaf strong = {} weak = {}", | |
Rc::strong_count(&leaf), | |
Rc::weak_count(&leaf), | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment