【发布时间】:2021-11-22 22:47:59
【问题描述】:
我正在尝试使用 Rust Actix Actor 框架,其中有一个线程轮询一些硬件,形成简单的事件消息并通过其 Addr 将它们发送到 Actor。有一个枚举 KeyingEvent 构成 Message。
在我的测试中,我有一个 Actor 捕获传入的 KeyingEvents,并记录它们以供测试验证:
struct CapturingKeyingEventReceiver {
received_keying_events: Vec<KeyingEvent>,
}
impl CapturingKeyingEventReceiver {
fn new() -> Self {
Self {
received_keying_events: vec![],
}
}
}
impl Actor for CapturingKeyingEventReceiver {
type Context = Context<Self>;
}
impl Handler<KeyingEvent> for CapturingKeyingEventReceiver {
type Result = ();
fn handle(&mut self, keying_event: KeyingEvent, _ctx: &mut Self::Context) {
info!("Keying Event {}", keying_event);
self.received_keying_events.push(keying_event);
}
}
我开始这个并得到它的地址:
let capturing_keying_event_receiver = CapturingKeyingEventReceiver::new().start();
这是一个 Addr,我可以将它传递给我的线程代码的构造函数....
但是在我的应用程序代码中,我有一个不同的 Actor,KeyingEventRouter,它也处理这些消息并将它们路由到各种其他子系统:
struct KeyingEventRouter {
...
}
impl Actor for KeyingEventRouter {
...
}
impl Handler<KeyingEvent> for KeyingEventRouter {
...
}
我遇到的问题是在我的线程代码构造函数中,我如何传递一个通用的Addr<???> 作为线程应该向其发送消息的目标actor? - 我尝试将构造函数中的参数指定为:
pub fn new(keying_event_receiver: Addr<dyn Actor>) -> Self {
...
但 Rust 不允许这样做:
help: specify the associated type: `Actor<Context = Type>`
我希望它能够将这些消息发送给Handler<KeyingEvent> 的任何参与者。如何让构造函数在我的测试中使用Addr<CapturingKeyingEventReceiver>,在我的应用程序代码中使用Addr<KeyingEventRouter>?
在 Java 中(有点手忙脚乱)我会创建一个接口 KeyingEventReceiver,让 CapturingKeyingEventReceiver 和 KeyingEventRouter 继承它,并传递一个 Addr<KeyingEventReceiver>..... 但是你怎么说'impl来自 KeyingEventReceiver 的 Actor,因为 KeyingEventReceiver 必须是一个具体的结构?
【问题讨论】:
-
我仍然对此问题的解决方案感兴趣,以进一步了解使用 Rust 的设计/限制。我找到了一种方法来实现我的手动 Java 方法的想法 - 如果你有一个
Actor<CapturingKeyingEventReceiver>,你可以获得它的Addr<CapturingKeyingEventReceiver>,然后调用recipient()函数。这会给你一个Recipient<KeyingEvent>,这将是我的测试和生产代码中的相同类型。即使使用上述方法,我也无法让我的代码与 Actix 一起使用;文档非常稀少,所以正在尝试 Riker。
标签: rust rust-actix