在没有var的actors中Scala保持状态
在另一种语言中,我使用新状态来维护它,但我不知道如何使用scala actors来实现这一点。我会这样设想:在没有var的actors中Scala保持状态,scala,actor,Scala,Actor,在另一种语言中,我使用新状态来维护它,但我不知道如何使用scala actors来实现这一点。我会这样设想: def act(state) react { case blah => act(doSomething(state, blah)) } } 嗯。。有趣的事。我稍微调整了一下我的问题,发现它可以编译。我意识到所发生的一切就是我必须返回一个部分函数。我可以返回一个部分函数,其中有一个参数,所以 import scala.actors._ object MyActor
def act(state)
react {
case blah => act(doSomething(state, blah))
}
}
嗯。。有趣的事。我稍微调整了一下我的问题,发现它可以编译。我意识到所发生的一切就是我必须返回一个部分函数。我可以返回一个部分函数,其中有一个参数,所以
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"
}
}
}
导入scala.actors_
对象MyActor扩展了Actor{
def程序(s:Int){
反应{
案例输入:字符串=>
如果((s%10000)==0){
打印项次(s+,“+输入)
}
过程(s+1)
}
}
def act=proc(0)
}
对象测试者{
def main(参数:数组[字符串]):单位={
MyActor.start()
对于(s,还有两种方法可以在不使用vars的情况下将状态存储在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
}
}
或者,如果您需要保存在其他消息期间可访问的状态,则可以创建另一个参与者;然后需要通知给您打电话的人有关新参与者的信息:
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
}
}
就我个人而言,我认为这样做是愚蠢的。这样做效率很低(当状态发生变化时,必须创建一个新的参与者,并处理一个旧的参与者——而参与者并不是那么轻量级!),而且这会使代码大大复杂化。在大多数情况下,将可变状态安全地隐藏为private[this]var
,这样您就知道只有参与者本身可以更改其可变状态。或者,您可以不使用新的参与者,而是使用调用者应该传回的状态信息进行回复,但这稍微不那么安全,因为原则上,他们可以修改状态信息,而不只是传回同样。在这种情况下,明智的做法是将@tailrec注释添加到proc方法()。以确保您没有炸毁堆栈。谢谢。我确实运行了100万次以确保没有炸毁堆栈,但让编译器检查了这一点。我添加了它,它给了我一个错误,说它无法优化它,这有点奇怪,因为我本来以为100万次会炸毁堆栈。我的错误是@tailrec a此处的注释;proc调用不是最后一个调用;react是。因此它不能是尾部递归的。根据此线程,堆栈溢出不太可能发生。@thoredge尼斯分析此处。我认为第一个调用不能满足我的需要。客户端发送输入,而参与者本身发送自身状态——但它们永远不会在同一时间被处理ime,所以它不能同时访问状态和输入,这就是问题的关键。另外,我不明白你为什么说它短——它看起来并不比任何东西都短。第二个问题我不关注,而且肯定很复杂。另一个答案中的解决方案没有堆栈溢出问题,并且实现了所需的功能。我很抱歉我不知道你有什么问题。@taotree-我想它工作正常;我把邮箱过满误解为递归闭包生成。我把“两种方式”改为“两种其他方式”。