考虑以下代码(简化但可编译):
use std::sync::Arc;
pub trait ActorRef<Message> { /* ... */ }
pub trait Actor<Message> { /* ... */ }
pub trait ActorSpawner {
/// Spawns a new actor returning an actor ref
/// for passing messages to it.
fn spawn<Message,A,R>(actor: A) -> Arc<R>
where R: ActorRef<Message>, A: Actor<Message>;
}
是否可以实施ActorSpawner::spawn
或实现与其他签名相似的内容?
简化了问题中的代码,将其缩减为我无法解决的核心部分。
通常,Actor
应该具有可变状态,该状态由处理消息改变(示例中缺少处理方法)。您可以生成Actor
并可以通过ActorRef
与其进行通信(示例中缺少send方法)。
我想允许不同的方式产生&#34; Actor
。例如。消息处理可能发生在每个actor的一个线程上。或者可以在由其他actor共享的线程池上完成处理。
其他代码可能依赖于创建更多actor。使用的基础机制应该是抽象的。由于特质ActorSpawner
。
我们假设我们为Actor
和ActorRef
设置了一些虚拟实现:
struct NoopActor;
impl<Message> Actor<Message> for NoopActor {}
struct DeadRef;
impl<Message> ActorRef<Message> for DeadRef {}
现在应该可以使用这些虚拟实现以某种方式实现特征。
这是我的第一次尝试:
struct DeadActorSpawner;
impl ActorSpawner for DeadActorSpawner {
fn spawn<Message,A,R>(actor: A) -> Arc<R>
where R: ActorRef<Message>, A: Actor<Message>
{
Arc::new(DeadRef)
}
}
导致此错误:
error[E0308]: mismatched types
--> src/main.rs:29:18
|
29 | Arc::new(DeadRef)
| ^^^^^^^ expected type parameter, found struct `DeadRef`
|
= note: expected type `R`
found type `DeadRef`
或另一个:
struct DeadActorSpawner;
impl ActorSpawner for DeadActorSpawner {
fn spawn<Message,A,R>(actor: A) -> Arc<DeadRef>
{
Arc::new(DeadRef)
}
}
导致此错误:
error[E0053]: method `spawn` has an incompatible type for trait
--> src/main.rs:25:42
|
12 | fn spawn<Message, A, R>(actor: A) -> Arc<R>
| ------ type in trait
...
25 | fn spawn<Message, A, R>(actor: A) -> Arc<DeadRef> {
| ^^^^^^^^^^^^ expected type parameter, found struct `DeadRef`
|
= note: expected type `fn(A) -> std::sync::Arc<R>`
found type `fn(A) -> std::sync::Arc<DeadRef>`
我尝试了许多其他方面无济于事,包括为Message
和Actor
中的ActorRef
使用关联类型。
答案 0 :(得分:4)
是否可以实施
ActorSpawner::spawn
Yes,但我看来没有有用的实施
或用其他签名实现类似的东西
我相信你期待归还Arc<ActorRef<Message>>
。因此,您可以在不知道DeadActorSpawner
*类型的情况下使用ActorSpawner
到Dead
特征。
您实际执行的操作是尝试专门化spawn
函数以返回Arc<DeadRef>
。我修改了你的ActorSpawner
以返回一个特征对象:
pub trait ActorSpawner {
fn spawn<Message, A>(actor: A) -> Arc<ActorRef<Message>> where A: Actor<Message>;
}
struct DeadActorSpawner;
impl ActorSpawner for DeadActorSpawner {
fn spawn<Message, A>(actor: A) -> Arc<ActorRef<Message>>
where A: Actor<Message>
{
Arc::new(DeadRef)
}
}