关于如何初始化弱结构体字段的语法问题<dyn T + Send + Sync>

问题描述 投票:0回答:1

目标

我正在为结构体

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 初始化为空?

rust observer-pattern weak-references
1个回答
0
投票

Weak::new()
没有
?Sized
界限,所以这不能自然地完成。解决方法是创建一个实现该特征的类型的
Weak
。如果您没有可访问的此类类型,则可以创建这样的类型,该类型只会在所有方法中发生恐慌(因为它们永远不会被调用)。

例如:

impl Publisher {
    pub fn new() -> Publisher {
        let publisher = Publisher {
            observer: Mutex::new(Weak::<SomeTypeImplementingEventObserver>::new()),
        };
        publisher
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.