考虑以下代码(简化但可编译):
导致出现此错误:
或者另一个例子:
导致出现以下错误:
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
与其通信(示例中缺少发送方法)。
我想允许以不同的方式"生成"Actor
。例如,每个actor可能会有一个线程来处理消息。或者处理可能在共享线程池上完成。
其他代码可能依赖于创建进一步的actors。 应该抽象使用的底层机制。由于特质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>`
我已经尝试了许多其他方法,包括在Actor
和ActorRef
中使用关联类型来解决Message
的问题,但都没有成功。