Skip to content

Instantly share code, notes, and snippets.

@Jammyjamjamman
Last active May 13, 2022 21:40
Show Gist options
  • Save Jammyjamjamman/1aacb08ca774ab8f2051b227c1974ba5 to your computer and use it in GitHub Desktop.
Save Jammyjamjamman/1aacb08ca774ab8f2051b227c1974ba5 to your computer and use it in GitHub Desktop.
Playing with rust reference counting
// 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