I have two simple structures like that:
struct Foo {
}
struct Bar<'a> {
foo: &'a mut Foo;
}
impl Foo {
pub fn new() -> Foo {
Foo
}
}
impl<'a> Bar<'a> {
pub fn new(foo: &'a mut Foo) -> Bar<'a> {
Bar {
foo: foo,
}
}
}
So basically the structure Bar
needs a reference to a Foo
to work on. This is how I use it:
let mut foo = Foo::new();
let mut bar = Bar::new(&mut foo);
Now I want to create a "glue" structure to handle the creation of all these Foo
s and Bar
s. So I just want the structure Container
to have 1 Foo
, 1 Bar
.
I tried doing something like:
impl Container {
pub fn new() -> Container {
Container {
foo: Foo::new(),
bar: Bar::new(&mut foo),
}
}
}
But it doesnt work, I cannot reference the field foo
from the bar
initializer.
I basically want to mimic the following C++ code:
Container::Container() :
foo(),
bar(&foo)
{}
Any ideas on how to solve this? Of course using any kind of dynamic allocation/reference counting would be highly overkill here.
--- EDIT ---
To be clear, I want to create the Rust code equivalent to this C++ snippet:
struct Foo {
};
struct Bar {
Bar(Foo& f) : foo(f) {}
Foo& foo;
};
Foo f;
Bar b(f);
struct Container {
Container() : f(), b(f) {}
Foo f;
Bar b;
};
--- EDIT ---
Here is what I ended up doing, using Rc<>
.
use std::rc::Rc;
struct Foo {
pub bar: Rc<Bar>,
}
impl Foo {
pub fn new(bar: Rc<Bar>) -> Foo {
Foo {
bar: bar,
}
}
}
struct Bar {
a: u8,
}
impl Bar {
pub fn new() -> Bar {
Bar {
a: 42,
}
}
}
struct Container {
pub bar: Rc<Bar>,
pub foo: Foo,
}
impl Container {
pub fn new() -> Container {
let bar = Rc::new(Bar::new());
Container {
bar: bar.clone(),
foo: Foo::new(bar.clone()),
}
}
}
fn main() {
// Just checking that we get the same bar for both
// inside Container and inside Foo
let c = Container::new();
println!("{:p}", &*c.bar);
println!("{:p}", &*c.foo.bar);
// So from what I understand, here bar is on the stack
// then byte-copied to the heap where that Rc<> will point?
let bar = Bar::new();
println!("{:p}", &bar);
let foo = Foo::new(Rc::new(bar));
println!("{:p}", &*foo.bar);
// Sad story is that using this Rc<> I now use the "cuteness"
// and safety that I had with reference borrowing:
// struct Foo<'a> {
// bar: &'a mut Bar,
// }
// impl<'a> Foo<'a> {
// pub fn new(bar: &'a Bar) -> Foo<'a> {
// Foo { bar: bar }
// }
// }
// let bar = Bar::new();
// let foo = Foo::new(&bar);
}
But this is not really satisfying, I feel like I used a machine gun to kill a rabbit. Any insight greatly appreciated :(