Scala “使用”的替代方案;var";有演员的国家?
我发现自己经常和akka演员一起使用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
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就会震动。这叫做热交换。我真的很喜欢这种方法。