Hi there - I'm confused about how to get weak references to work. I want to have a single collection of owned objects and then multiple collections of weak references to those owned objects, so that dropping the owned objects doesn't require manually removing it from all of those other collections.
use std::collections::HashMap;
use std::rc::{Rc, Weak};
use std::vec::Vec;
fn main() {
// the authoritive list of owned objects keyed by their ID
let mut m = HashMap::<u32, Rc<u32>>::new();
// new scope to ensure a doesn't live longer and thus confusing intuition
{
let a = Rc::new(5);
m.insert(5, a);
}
// a collection of weak references to the strongly owned objects in m
let mut col1: Vec<Weak<u32>> = vec![];
// create a non-owning reference
col1.push(Rc::downgrade(m.get(&5).unwrap()));
// check my intuition
let x: Vec<Option<Rc<u32>>> = col1.iter().map(|i| i.upgrade()).collect();
println!("should be Some(5): {:?}", &x);
// Now drop the authoritively owned object
m.remove(&5);
// col1 should reference the DROPPED original RC and be None
let x: Vec<Option<Rc<u32>>> = col1.iter().map(|i| i.upgrade()).collect();
println!("should be None: {:?}, but is Some :-(", &x);
}
Gah - because the upgrade creates an owning reference - doh! Thanks!
use std::collections::HashMap;
use std::rc::{Rc, Weak};
use std::vec::Vec;
fn main() {
// the authoritive list of owned objects keyed by their ID
let mut m = HashMap::<u32, Rc<u32>>::new();
// new scope to ensure a doesn't live longer and thus confusing intuition
{
let a = Rc::new(5);
m.insert(5, a);
}
// a collection of weak references to the strongly owned objects in m
let mut col1: Vec<Weak<u32>> = vec![];
// create a non-owning reference
col1.push(Rc::downgrade(m.get(&5).unwrap()));
{
// check my intuition
let x: Vec<Option<Rc<u32>>> = col1.iter().map(|i| i.upgrade()).collect();
println!("should be Some(5): {:?}", &x);
}
// Now drop the authoritively owned object
m.remove(&5);
// col1 should reference the DROPPED original RC and be None
let x: Vec<Option<Rc<u32>>> = col1.iter().map(|i| i.upgrade()).collect();
println!("should be None: {:?}", &x);
}
thanks - I realised that ;-). It didn't click that the vector handing around would (of course) keep the references alive. This was all to test my intuition but I flummoxed myself with "testing" my intuition by creating that vector, which had an expected side effect.