Scala “使用”的替代方案;var";有演员的国家?

Scala “使用”的替代方案;var";有演员的国家?,scala,akka,actor,Scala,Akka,Actor,我发现自己经常和akka演员一起使用VAR来维持状态。例如,如果我的参与者需要维护项目列表,我可能会执行以下操作: class ListActor extends Actor{ var xs : List[Int] = List() def receive = { case x : Int => xs = x :: xs } } 使用可变变量似乎违背了Scala的精神。或者,我使用了以下方法: class ListActor2 extends Actor{ im

我发现自己经常和akka演员一起使用VAR来维持状态。例如,如果我的参与者需要维护项目列表,我可能会执行以下操作:

class ListActor extends Actor{
  var xs : List[Int] = List()

  def receive = {
    case x : Int => xs = x :: xs
  }
}
使用可变变量似乎违背了Scala的精神。或者,我使用了以下方法:

class ListActor2 extends Actor{
  import context._

  def collect_ints(accu : List[Int]) : Receive = {
    case x : Int => become(collect_ints(x :: accu))
  }

  def receive = collect_ints(Nil)
}
我更喜欢它的外观,但是我需要担心堆栈溢出吗

我知道FSM的特点,以前也用过,但在某些情况下,它似乎太多了

维护简单状态的推荐方法是什么?还有其他我不知道的选择吗


另外,如果我发现自己经常需要可变变量,这通常是一个坏兆头吗?我没有正确使用actor模型吗?

对于actor模型中的简单状态,我看不出
var有任何问题

通过设计,Akka可以防止参与者的状态因并发访问状态变量而被破坏或锁定


只要不使用将您的状态暴露给其他线程,使用
var
作为简单状态就不会有问题。

有两种
been
方法:一种是将行为推送到堆栈上,另一种是不推送到堆栈上。后者是默认值,因此您不必担心行为堆栈变得太大。使用
been
以这种方式管理状态是非常有效的用法。

实际上是一种非常简洁的习惯用法,用于维护参与者系统中的状态,如本例所示:

sealed trait State
case object Active extends State

class ListActor extends Actor with FSM[State,List[Int]] {

  startWith(Active,List[Int]())

  when(Active) {
    case Event(x:Int,xs) => stay using x :: xs
  }
}

在使用了这里讨论的所有备选方案后,FSM将我的票投给任何比琐碎更复杂的事物。

我个人喜欢使用
been
的方法。这看起来很像您在Erlang中所做的,并且非常实用。而且它不是真正的递归,所以你根本不必担心堆栈溢出。如果你不想使用
var
s,那么
been
就是最好的选择<代码>变成
不会再次出现,它只是一条指令,指示参与者上下文用新的行为替换参与者的行为。它不消耗堆栈。此外,您可以使用可变数据结构而不是
var
s:您的第一个示例可以使用
mutable.ListBuffer
类重写。在大多数情况下,它的性能应该更高。使用只有一个状态的有限状态机似乎更。。。奇怪。是的,这是非常奇怪的,但是一个只向列表中添加一个整数的参与者也是奇怪的:)如果你有很多状态,FSM就会震动。这叫做热交换。我真的很喜欢这种方法。