Last active
May 13, 2022 21:40
-
-
Save Jammyjamjamman/1aacb08ca774ab8f2051b227c1974ba5 to your computer and use it in GitHub Desktop.
Playing with rust reference counting
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
// import commonly used items from the prelude: | |
// use rand::prelude::*; | |
use std::{ rc::Rc, cell::RefCell }; | |
fn destroy<T>(_: T) { | |
} | |
fn main() { | |
let val = Rc::new(5); | |
// Weak refs do not add to the reference count. So if val is destroyed/ freed, | |
// so is the inner value and you won't be able to get the value from val_weak. | |
let val_weak = Rc::downgrade(&val); | |
// upgrade converts the weakref to a strong ref so we can get a reference to the value. | |
println!("val is {} and val_weak is {}", val.as_ref(), val_weak.upgrade().expect("Could not upgrade to strong ref.").as_ref()); | |
// Destroy (move) value. | |
destroy(val); | |
if let Some(val_ref) = val_weak.upgrade() { | |
println!("val weak is {}", val_ref.as_ref()); | |
} | |
else { | |
println!("Could not get value from (weak) ref as all strong refs are destroyed."); | |
} | |
// We need refcell if we want to modify the value inside. | |
let val2 = Rc::new(RefCell::new(7)); | |
// Strong ref, so adds to the ref count. Destroying val2 will now not destroy the inner value. | |
let val2_strong = Rc::clone(&val2); | |
let val2_weak = Rc::downgrade(&val2); | |
println!("val2 is {} and val2_weak is {}", val2.as_ref().borrow(), val2_strong.as_ref().borrow()); | |
*val2.as_ref().borrow_mut() = 8; | |
// Both values should now be 8. | |
println!("val2 is {} and val2_weak is {}", val2.as_ref().borrow(), val2_strong.as_ref().borrow()); | |
destroy(val2); | |
// We still have a strong ref, so the upgrade should work. | |
if let Some(val_ref) = val2_weak.upgrade() { | |
println!("val2 strong is {}", val_ref.as_ref().borrow()); | |
} | |
else { | |
println!("Could not get value from (weak) ref as all strong refs are destroyed."); | |
} | |
// Other things to lookup: | |
// * Cell. Like RefCell, but for copy values instead of clone (immutable). | |
// * Arc variants, for threaded reference sharing. | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment