如果scala主张不变性为什么它采用具有可变性质的演员模型?

时间:2017-04-09 08:20:14

标签: scala functional-programming akka immutability actor-model

我是斯卡拉和演员界的新人。

这是我迄今为止所学到的:

Scala是函数式编程(不是纯粹的),人们建议不要在scala中使用可变状态。

但另一方面,有一个实现actor模型的akka​​框架。在玩akka期间,我意识到消息是不可变的,但是MUTABLE中的演员状态。所以,我需要指定演员内部" var"变量和可变集合。并且,对我来说,拥有一个可变状态对于scala来说并不自然。

那么,我的理解是否正确? 为什么人们在不变的scala语言中采用了可变的actor模型?

3 个答案:

答案 0 :(得分:9)

这是一个有趣的观点,实际上演员与其他类似Scala的代码完全不同。

您可以将actor视为具有锁,信号量和其余部分的线程的替代品。它是一种更直观,更高效的并发编程模型,因为可变状态总是封装在一个按顺序处理消息的actor中。

它为构建更多功能抽象提供了坚实的基础。 Akka团队制作了akka-streams。 Spark正在使用akka跨节点进行通信。 Future,问题的另一个成功的功能替代方案本质上是流的特殊情况:恰好一个元素的流,可以使用actor实现。

因此,人们使用actor是因为通过让演员互相发送消息而不是使用流上的操作来更直观地解决某些问题。由于反对可变性的主要论点是它在并发上创造的完全混乱,并且演员解决了这个问题,我想可以有这种可变性。它们相当复杂,但正确的并发解决方案实际上很复杂。

简而言之,流可以说是模拟程序与其环境的任何交互的功能方式。例如。对于GUI开发,您可以将所有触发的控件事件作为流提供,折叠流实际上是创建一种管理程序状态的方法。

答案 1 :(得分:3)

Scala是一种允许混合模型的语言。很遗憾,大多数示例在Actors中使用可变状态,但您可以使用become使用具有不可变状态的Actors:

class ListActor extends Actor {
  def receive = changeState(List.empty[String])

  def changeState(state: List[String]): Receive = {
    case Add(item) =>
      context.become(changeState(item :: state))
  }
}

答案 2 :(得分:3)

这是一个很好的问题,有一个有趣的答案(恕我直言):Scala不起作用。它是post-functional。这意味着它unifies object oriented and functional programming成为一个范例。

在此框架内,Scala支持不变性,但不强制执行。 Actor模型是可变性有意义的地方,因为所有更改都是本地的,并发行为系统会为您完成并发行为的协调。