2011-01-07 69 views
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,編譯器都會抱怨以下幾行:

type mismatch;發現:需要scala.actors.Actor: com.myCompany.test.MyActor

或其他各種投訴。我知道這與匿名課程一定很簡單,但我現在看不到它。有什麼建議麼?提前致謝!!

回答

1

如何:

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

     myActorMap("group2") ! Update 
    } 
+0

工作,謝謝。 – 2011-01-08 15:40:10

+0

雖然不是很FP。我認爲雷克斯的方法(continuation-passing style?)可能有助於在不同情況下使代碼最小化。 – 2011-01-08 17:12:14

3

的問題start的是,它並不知道真正的類型的演員。因此,它返回一個通用的。爲了解決這個問題,你需要一個緊湊的方式來啓動它,然後返回你實際擁有的actor(不是超類)。實際上,這聽起來像是一個普遍有用的功能,不是嗎? - 接受一個對象,讓它做某件事,然後返回該對象?

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,這種功能在一般情況下非常有用,以至於你可能想把它放到你的個人代碼片段中,這是我的。你有一個,不是嗎?)