Let's assume I've got an aggregator struct, which has a vector of references to objects ("workers"), the methods of which need to be called on demand. The catch is: these workers also need to have a reference to the aggregator, which they must be able to call once the work is done. For instance:
struct A<'w> {
v: Vec<&'w W<'w>>
}
impl<'w> A<'w> {
fn do_some_work(&self) {
for w in self.v {
w.work();
}
}
fn finish(&self) {
println!("done!");
}
}
struct W<'a> {
data: i32
agg: &'a A<'a>
}
impl<'a> W<'a> {
fn work(&self) {
println!("working with {}", self.data);
self.agg.finish();
}
}
This seems intuitively correct, but turns out to be impossible (?) to implement in reality:
fn main() {
let mut a = A { v: Vec::new() };
let w = W { data: 101, agg: &a };
a.v.push(&w); // nope, modifying an immutably borrowed reference
}
What am I doing wrong? Which constructs can be used to make such things possible? Can it be done without using any Cell
-like types for the aggregator (such as <Cell<Vec<&W>>
?) How would you do it?