Scala 非类型与类型转换器-为什么使用非类型?

Scala 非类型与类型转换器-为什么使用非类型?,scala,akka,scalability,distributed,actor,Scala,Akka,Scalability,Distributed,Actor,我试图理解为什么人们会使用非类型的演员。 我读过几篇关于这方面的文章,其中一些如下: 我有兴趣了解为什么非类型演员在以下方面更好: 网络服务器 分布式体系结构 可扩展性 与用其他编程编写的应用程序的互操作性 语言 我知道,由于been/unbecome功能,在FSM的上下文中,非类型参与者更好 我可以在负载平衡器中看到非类型化的可能性,因为它不必知道消息的内容,只需将消息转发给其他参与者即可。然而,这也可以在typedactor中实现 有人能在上面提到的非类型参与者“更好”的领域提出一些用

我试图理解为什么人们会使用非类型的演员。 我读过几篇关于这方面的文章,其中一些如下:

我有兴趣了解为什么非类型演员在以下方面更好:

  • 网络服务器
  • 分布式体系结构
  • 可扩展性
  • 与用其他编程编写的应用程序的互操作性
    语言
我知道,由于been/unbecome功能,在FSM的上下文中,非类型参与者更好

我可以在负载平衡器中看到非类型化的可能性,因为它不必知道消息的内容,只需将消息转发给其他参与者即可。然而,这也可以在typedactor中实现


有人能在上面提到的非类型参与者“更好”的领域提出一些用例吗?

类型参与者有一个普遍的缺点:它们很难扩展。当您使用普通特征时,您可以轻松地将它们组合起来,以构建实现这两个接口的对象

trait One {
  def callOne(arg : String)
}
trait Two {
  def callTwo(arg : Double)
}
trait Both extends One with Two
Both
trait支持由两个trait组合而成的两个调用

如果您使用actor方法来处理消息而不是直接调用,那么您仍然能够扩展接口,以拒绝类型安全作为代价

trait One {
  val receiveOne : PartialFunction[String,Unit] = {
    case msg : String => ()
  } 
}
trait Two {
  val receiveTwo : PartialFunction[Double, Unit] = {
    case msg : Double => ()
  }
}
trait Both extends One with Two {
  val receive : PartialFunction[Any, Unit] = receiveOne orElse receiveTwo
}
Both
trait中的
receive
值结合了两个部分函数。第一个只接受
String
s,第二个只接受
Double
s。它们有一个公共超类型:
Any
。所以扩展版本应该使用
Any
作为参数,并有效地取消类型化。该漏洞存在于scala类型系统中,该系统支持使用带关键字的
进行类型乘法,但不支持联合类型。无法定义双精度或字符串

类型化的参与者失去了易于扩展的能力。Actors将类型检查转移到逆变位置,扩展它需要联合类型。您可以在编程语言中看到它们是如何工作的

这并不是说非类型化的参与者和类型化的参与者有不同的应用领域。所有被质疑的功能都可以用这两者来表示。选择更多的是方法和方便

键入允许您在进行单元测试之前避免一些错误。它将花费辅助协议声明的样板文件。在上面的示例中,您应该显式声明联合类型:

trait Protocol
final case class First(message : String) extends Protocol
final case class Second(message : Double) extends Protocol
而且你失去了简单的回调组合:没有适合你的
orElse
方法。只有手写的

val receive : PartialFunction[Protocol, Unit] = {
   case First(msg) => receiveOne(msg)
   case Second(msg) => receiveTwo(msg)
}
如果您想在trait
Three
中添加一些新功能,那么您将忙于重写样板代码

Akka为参与者提供了一些有用的预定义增强功能。他们通过mixin(例如)或delegate(例如)添加新功能。代理模式在akka应用程序中使用得非常多,它们会动态地更改协议,向协议添加控制命令。这在打字演员身上是不容易做到的。因此,您将被迫编写自己的实现,而不是预定义的实用程序。而被抛弃的公用事业也不会受到FSM的限制


这取决于你决定打字的改进是否值得增加工作。如果不深入了解您的项目,没有人能给出准确的建议。

类型演员是非常新的

警告

本模块目前处于实验阶段,是积极研究的主题。这意味着API或语义可以在没有警告或弃用期的情况下更改,并且在您收到警告之前,不建议在生产中使用此模块


(截至本文撰写之时)

我想指出这里似乎出现了一种困惑。 Casper,您提到的“类型化参与者”已被弃用,甚至最终将被删除,我已经详细解释了为什么会出现这种情况:。你找到的与Viktor Klang的链接是关于Akka 1.2的,它到现在为止是“古老的”(2.4是稳定版本)

话虽如此,有一个新的实验模块叫做“”,Daynyth在他的回答中提到了这个模块。该模块可能确实会成为一个新的核心抽象,但它还没有准备就绪

我建议您提供类型化的模块:(Akka的最新添加,它不会很快成为实验性的)和
看看演员们在不久的将来(也许)会如何打字。然后,再看看哪个模型最适合您的用例。非类型化的演员有一个真正的和尝试成熟的模块/模型的优点,所以如果你想要更多的类型,你可以真正信任他们,如果你在很多情况下覆盖了AKKa流,但不是全部,那么你可以考虑实验模块(但是要知道,我们最有可能在成熟的时候改变类型化的API)。.

你能把这与我提到的上下文联系起来吗?我能理解你的例子,但我不明白为什么这是一个大问题。@CasperThuleHansen你的问题太宽泛了,我想说这个问题以一种理智的方式解决了这个问题。对不起,但我不同意。我正在寻找一些用例,其中非类型化抽象比类型化抽象更好。FSM是其中之一,还有更多吗?我已经重新表述了我最初的问题,以使其更加清晰。我对新的Akka类型非常感兴趣,但由于它是实验性的,现在很难证明使用它是合理的。我是说Akka类型的演员。然而,据我所知,它并没有被弃用,但它将被弃用。你的帖子很好,我读了卡尔·休伊特的原创文章。然而,似乎如果我没有使用FSM,就没有理由使用非类型的参与者。我可以用一种更广义的方式使用更多的“为什么”。在接下来的评论中,我将寻找一些类似于上一个论点的用例。第一个论点是非常具体的实现,正如第二个论点中提到的,我已经在使用futures