I am working on a pub/sub model that looks like this:
trait EventObserver { ... }
struct Publisher {
observer: Mutex<Weak<dyn EventObserver + Send + Sync>>,
}
How do I initialize the Publisher with a Weak set to nothing?
If I write it like this:
impl Publisher {
pub fn new() -> Publisher {
Publisher {
observer: Mutex::new(Weak::new()),
}
}
}
The compiler says:
error[E0283]: type annotations needed
--> src/lib.rs:12:34
|
12 | observer: Mutex::new(Weak::new()),
| ^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Weak`
|
= note: cannot satisfy `_: Unsize<dyn EventObserver + Send + Sync>`
= note: required for the cast from `std::sync::Weak<_>` to `std::sync::Weak<(dyn EventObserver + Send + Sync + 'static)>`
help: consider specifying the generic argument
|
12 | observer: Mutex::new(Weak::<T>::new()),
| +++++
And if I specify the type is dyn EventObserver + Send + Sync, the compiler says:
error[E0599]: the function or associated item `new` exists for struct `Weak<dyn EventObserver + Send + Sync>`, but its trait bounds were not satisfied
--> src/lib.rs:12:75
|
3 | trait EventObserver {}
| ------------------- doesn't satisfy `dyn EventObserver + Send + Sync: Sized`
...
12 | observer: Mutex::new(Weak::<dyn EventObserver + Send + Sync>::new()),
| ^^^ function or associated item cannot be called on `Weak<dyn EventObserver + Send + Sync>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`dyn EventObserver + Send + Sync: Sized`
I am just looking for a way to initialize the Weak to nothing, so it's expected that any upgrade of the observer will fail to find a valid pointer. After subscribe() is called, then the later upgrade of the Weak can succeed.
I do know two workarounds, one is to use Option to wrap the Weak, another is to create a struct that impl the trait. Is there a clean way just to initialize the Weak<dyn T + Send + Sync> to nothing compared to these workarounds?
Weak::new()doesn't have a?Sizedbound, so this cannot be done naturally. The fix is to create aWeakof a type that implement the trait. If you don't have such type accessible, you can create such type that just panics in all methods (since they'll never be called anyway).For example: