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

2番目のインスタンスを取得して開始させますが、もっと次のようなことができるようにしたいと思います:

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

しかし、新しいアクタをどのようにラップしても、コンパイラは次のようなエラーを出します:

型の不一致; 見つかった: 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 に答える