演员信息应该扩展一个共同的特征吗?

par*_*tic 11 scala actor akka

在正确使用scala(和akka)actor框架的大多数示例中,人们倾向于从单个特征中获取每条消息.例如:

trait Message
object Ping extends Message
object Pong extends Message
Run Code Online (Sandbox Code Playgroud)

但是,在Scala和Akka中,消息接收都没有输入.有没有理由实施共同特征?

fre*_*oma 5

这实际上取决于你想要达到的目标.例如,我最近构建了一个使用actor的小应用程序,这些actor有几种类型的actor,还有一个管理actor,它或多或少像路由器一样.现在,工作人员可以收到许多不同的消息,例如Foo,BarBaz.如果没有Supertype,在管理演员中,我必须写下这样的东西:

react {
    case x:Foo | x:Bar | x:Baz => worker ! x
}
Run Code Online (Sandbox Code Playgroud)

这显然是不必要的冗长.所以在这种情况下,超类型WorkerMessage会很有意义,因为它简化了代码:

react {
    case x:WorkerMessage => worker ! x
}
Run Code Online (Sandbox Code Playgroud)

另一方面,这会产生消息Foo,Bar并且Baz除了由WorkerActors使用之外,几乎不能用于任何其他目的.如果您有消息Stop或者Init例如,这可能会很糟糕,因为您需要在整个地方重新定义它.

因此,如果你知道你只有不会传递信息的演员(也就是说,他们自己处理它们),那么我猜你没有超类型就可以了.

我想人们在默认情况下或多或少地做这件事的原因是,如果你以后改变你的代码,你不必在之后创建特征,因为你已经在开始时做了.

就个人而言,我总是尽量避免不必要的开销,所以除非我真的需要,否则我可能不会定义超类型.另外,我真的不知道创建超类型是否对性能有任何影响,但我很有趣.


Vas*_*iuk 5

  1. 使用scala.actors(via InputChannel[T]Reactor[T])和Akka(TypedActor)都可以为传入消息设置类型边界;

  2. 在大多数示例中,消息扩展了一个sealed trait.这样做有两个原因:

    • 如果你的actor的消息处理程序(部分函数)没有覆盖所有扩展特征的消息,编译器会生成一个警告 ;

    • sealed trait 只能在定义特征的源文件中扩展,因此客户端无法定义扩展特征的消息;

  • 好的,我现在看到了scala.actors的原因.但是,对于akka类型的actor你没有定义消息,你只需调用你的接口方法并等待魔法发生.密封特性是有用的,但如果我没记错的话Akka接收是一个部分功能[Any,Unit],所以不检查丢失的情况. (2认同)