目标
我正在为结构体
Publisher
开发订阅者/发布者模式。所以观察者是
trait EventObserver {
fn update_info(&self, info: Information) -> Result<(), Error>;
}
现在,发布者有一个受
std::sync::Mutex
保护的字段
struct Publisher {
observer: Mutex<Weak<dyn EventObserver + Send + Sync>>,
}
问题是,如何将带有Weak的Publisher初始化为空?稍后,我将使用另一个函数“subscribe”来设置观察者。请注意,Weak 类型有 Send 和 Sync,因为该 Publisher 的调用者也需要获取 future。因此,如果没有这些,编译器会抱怨该类型不是 Send 和 Sync。
问题
如果我写的不同会有不同的编译错误
impl Publisher {
pub fn new() -> Publisher {
let publisher = Publisher {
observer: Mutex::new(Weak::new()),
};
publisher
}
}
错误是“无法推断在结构
T
上声明的类型参数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 publisher::EventObserver + std::marker::Send + std::marker::Sync: std::marker::Sized`
问题
我只是在寻找一种将 Weak 初始化为空的方法,因此预计
observer
的任何升级都将无法找到有效的指针。调用subscribe
后,Weak后面的升级就可以成功了。
我确实知道两种解决方法,一种是使用 Option 来包装 Weak,另一种是创建一个实现该特征的结构。与这些解决方法相比,是否有一种干净的方法可以将这个
Weak::new()
没有 ?Sized
界限,所以这不能自然地完成。解决方法是创建一个实现该特征的类型的 Weak
。如果您没有可访问的此类类型,则可以创建这样的类型,该类型只会在所有方法中发生恐慌(因为它们永远不会被调用)。
例如:
impl Publisher {
pub fn new() -> Publisher {
let publisher = Publisher {
observer: Mutex::new(Weak::<SomeTypeImplementingEventObserver>::new()),
};
publisher
}
}