Reputation: 41
I want to create a registry of objects that all implement some trait. So the Registry struct has a register function. But if I declare it returning void type, I can only register one object, then borrow issue for the second one. I found a work around: the register function returns self as mutable, then I an reuse the registry returned and the compiler is OK. I found this a bit ridiculous. What is the proper way to maintain a registry of objects ? Here is the code that works
trait Doable {
fn do_it(&mut self);
}
struct Registry<'a> {
components: Vec<Box<&'a (dyn Doable)>>,
}
impl<'a> Registry<'a> {
fn register(&'a mut self, d: &'a impl Doable) -> &mut Registry<'a> {
self.components.push(Box::new(d));
self
}
}
struct Foo {
name: String,
value: u32,
}
impl Foo {
fn set_value(&mut self, v: u32) {
self.value = v
}
}
impl Doable for Foo {
fn do_it(&mut self) {
println!("The value of {} is {}", self.name, self.value);
}
}
struct Bar {
nm: String,
id: u32,
}
impl Bar {
fn set_id(&mut self, v: u32) {
self.id = v
}
}
impl Doable for Bar {
fn do_it(&mut self) {
println!("The id of {} is {}", self.nm, self.id);
}
}
fn main() {
let mut r = Registry {
components: Vec::new(),
};
let mut foo: Foo = Foo {
name: "foo".to_string(),
value: 0,
};
let mut bar: Bar = Bar {
nm: "bar".to_string(),
id: 0,
};
let mut baz: Foo = Foo {
name: "baz".to_string(),
value: 0,
};
let r1 = r.register(&foo);
let r2 = r1.register(&bar);
r2.register(&baz);
foo.set_value(41);
bar.set_id(5);
baz.set_value(11);
foo.do_it();
bar.do_it();
baz.do_it();
}
it works but I would like to have a better way for registering objects and then call them back using the trait...
Upvotes: 0
Views: 38