Reputation: 18331
Trying to implement a data structure where many "things" can be owned by an "owner", while each "thing" should know who its owner is. As far as I understand it can be achieved by having a Weak reference to the owner in each "thing". The question I cannot figure out how to implement the constructor (new
) function for these structures. Here is a simplified structure of what I am trying to do:
use std::rc::{Rc, Weak};
struct Owner {
thing1: Thing,
thing2: Thing,
}
impl Owner {
fn new() -> Self {
Self {
thing1: Thing::new(???), // 1
thing2: Thing::new(???), // 1
}
}
}
struct Thing {
owner: Weak<Owner>,
value: u32,
}
impl Thing {
fn new(owner: ???) -> Self { // 2
Self {
owner: Weak::clone(???), // 2
value: 0,
}
}
}
So here I can't figure out two things:
Perhaps my approach is completely wrong, in this case please suggest the right one.
Update:
A more concrete example of a use-case for such a structure:
Consider an electronic circuit simulation, where each "thing" is a pin of an electronic component, which is the "owner". So each time the value of a pin is externally changed, it should trigger the owner component, which in turn will change the other connector values.
Upvotes: 2
Views: 784
Reputation: 5618
First, as others have mentioned, this is likely a bad idea that will not only cause poor performance but will be very difficult to code with. With that warning, on to the answer.
This is a bit tricky because today in stable Rust, you would need to initialize the owner in order to get a reference to it (so you would probably need each field to be Option<Thing>
; not ideal).
However, as luck would have it, there is an new unstable method Rc::new_cyclic
which I think does exactly what you want:
#![feature(arc_new_cyclic)]
use std::rc::{Rc, Weak};
struct Owner {
thing1: Thing,
thing2: Thing,
}
impl Owner {
fn new() -> Rc<Self> {
Rc::new_cyclic(|weak| {
Self {
thing1: Thing::new(weak.clone()),
thing2: Thing::new(weak.clone()),
}
})
}
}
struct Thing {
owner: Weak<Owner>,
value: u32,
}
impl Thing {
fn new(owner: Weak<Owner>) -> Self {
Self {
owner,
value: 0,
}
}
}
Upvotes: 2