I have an observable collection and an observer. I want the observer to be a trait implementation of trait Observer
. The observable object should be able to notify each observer when some event occurs. This should explain my intentions:
struct A {
observables: Vec<Observable>,
}
impl A {
fn new() -> A {
A {
observables: vec![],
}
}
}
trait Observer {
fn event(&mut self, _: &String);
}
impl Observer for A {
fn event(&mut self, ev: &String) {
println!("Got event from observable: {}", ev);
}
}
struct Observable {
observers: Vec<dyn Observer>, // How to contain references to observers? (this line is invalid)
}
impl Observable {
fn new() -> Observable {
Observable {
observers: Vec::new(),
}
}
fn add_observer(&mut self, o: &dyn Observer) {
// incorrect line too
self.observers.push(o);
}
fn remove_observer(&mut self, o: &dyn Observer) {
// incorrect line too
self.observers.remove(o);
}
fn notify_observers(&self, ev: &String) {
for o in &mut self.observers {
o.event(ev);
}
}
}
I get the error:
error[E0277]: the size for values of type `(dyn Observer + 'static)` cannot be known at compilation time
--> src/lib.rs:24:5
|
24 | observers: Vec<dyn Observer>, // How to contain references to observers?
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `(dyn Observer + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required by `std::vec::Vec`
This is just a mock-up of what I want to do. I have code like this in Java, Python, and C++, but I don't know how to implement the observer pattern in Rust. I believe my problem is in storing a reference to observer objects inside observable objects.
Observer
unregister from theObservable
? How is the lifetime of anObserver
handled? – Matthieu M.