在另一种语言中,我有一些东西用新状态来调用它来维护它但我不知道如何用scala actor来做到这一点。这样的事情是我想象的:
def act(state)
react {
case blah => act(doSomething(state, blah))
}
}
答案 0 :(得分:1)
import scala.actors._
object MyActor extends Actor {
def proc(s: Int) {
react {
case input: String =>
if ((s % 10000) == 0) {
println(s + ", " + input)
}
proc(s + 1)
}
}
def act = proc(0)
}
object TestActors {
def main(args: Array[String]): Unit = {
MyActor.start()
for (s <- 1 to 10000000) {
MyActor ! "a message"
}
}
}
好处是,通过稍微调整一下,它可以很容易地推广。
答案 1 :(得分:0)
还有另外两种方法可以在不使用变量的情况下在actor中存储状态。如果您只需要向前传递状态,则可以让actor向自己发送消息:
object MailsSelf {
import scala.actors._
class Selfish extends Reactor[Any] {
def act() { loop { react {
case i: Int if (i>=0) =>
println(i)
this ! (i-1) // Self-messaging instead of recursive call
case _ => exit
}}}
}
def main(args: Array[String]) {
(new Selfish).start() ! 5
}
}
或者,如果您需要保存在其他消息期间可访问的状态,则可以创建另一个actor;无论谁打电话给你,都需要了解这位新演员:
object EndlessActors {
import scala.actors._
class Delegater(n: Int) extends ReplyReactor {
def act() { loop { react {
case i: Int if (i*n >= 0) =>
println(i*n)
val next = new Delegater(n-1)
next.start()
reply(Some(next))
case _ => reply(None); exit
}}}
}
def main(args: Array[String]) {
val original = new Delegater(5)
original.start()
Iterator.iterate( Option(original) ){ maybe =>
maybe.flatMap(d => {
val result = (d !? 5)
result match {
case Some(d2: Delegater) => Some(d2)
case _ => None
}
})
}.takeWhile(_.isDefined).foreach(_ => {}) // Foreach forces evaluation
}
}
就个人而言,我认为以这种方式做事是愚蠢的。效率非常低(必须创建一个新的actor,并且随时更改旧的actor状态 - 而且actor 轻量级!),这使代码变得非常复杂。在大多数情况下,将可变状态安全地隐藏为actor中的private[this] var
更为实际,这样您就知道只有actor本身可以改变其可变状态。或者,您可以不使用新的actor回复,但可以回复调用者应该传回的状态信息,但这稍微不那么安全,因为他们原则上可以修改状态信息而不是再次传回状态信息。