Scala在没有var的actor中保持状态

时间:2011-04-27 22:17:19

标签: scala actor

在另一种语言中,我有一些东西用新状态来调用它来维护它但我不知道如何用scala actor来做到这一点。这样的事情是我想象的:

def act(state)
  react {
    case blah => act(doSomething(state, blah))
  }
}

2 个答案:

答案 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回复,但可以回复调用者应该传回的状态信息,但这稍微不那么安全,因为他们原则上可以修改状态信息而不是再次传回状态信息。

相关问题