0

我正在试验一张演员地图,并想知道如何实例化它们并一举启动它们......

import scala.actors.Actor
import scala.actors.Actor._
import scala.collection.mutable._

abstract class Message
case class Update extends Message

object Test {
    val groupings = "group1" :: "group2" :: "group3":: Nil
    val myActorMap = new HashMap[String,MyActor]

    def main(args : Array[String]) {
        groupings.foreach(group => myActorMap += (group -> new MyActor))
        myActorMap("group2").start
        myActorMap("group2") ! Update
    }
}

class MyActor extends Actor {
    def act() {
        loop {
            react {
                case Update =>
                    println("Received Update")
                case _ =>
                    println("Ignoring event")
            }
        }
    }   
}

该行:

    myActorMap("group2").start

将抓住第二个实例,让我开始它,但我希望能够做更多类似的事情:

        groupings.foreach(group => myActorMap += (group -> (new MyActor).start))

但无论我如何包装新的 Actor,编译器都会抱怨以下内容:

类型不匹配; 找到:scala.actors.Actor 需要:com.myCompany.test.MyActor

或其他各种投诉。我知道使用匿名类一定很简单,但我现在看不到。有什么建议么?提前致谢!!

4

2 回答 2

3

问题start在于它不知道演员的真实类型。因此,它返回一个通用的。为了解决这个问题,您需要一种紧凑的方式来启动它并仍然返回您实际拥有的演员(不是超类)。实际上,这听起来像是一个有用的功能,不是吗?——获取一个对象,让它做某事,然后返回该对象?

class SideEffector[A](a: A) {
  def effect(f: A => Unit) = { f(a); a }
}
implicit def everythingHasSideEffects[A](a: A) = new SideEffector(a)

现在你可以

(new MyActor).effect(_.start)

并且类型将被保留。(如果您不使用 Scalaz,这种功能通常非常有用,您可能希望将其放入您的个人方便代码片段库中。它在我的。你有一个,不是吗?)

于 2011-01-07T22:14:18.737 回答
1

这个怎么样:

    def main(args : Array[String]) {
      groupings.foreach {
        group =>
        val actor = new MyActor
        actor.start
        myActorMap += (group -> actor)
      }

      myActorMap("group2") ! Update
    }
于 2011-01-07T20:31:52.383 回答