我有2個角色處理消息,男演員發送消息到演員B.演員B,則應該處理這些數字並打印在同一行與演員
我的代碼:
class ActorB extends Actor{
def receive = {
case 0 => println("0")
case x : Int => println (x)
}
}
但韓元「T編譯
我有2個角色處理消息,男演員發送消息到演員B.演員B,則應該處理這些數字並打印在同一行與演員
我的代碼:
class ActorB extends Actor{
def receive = {
case 0 => println("0")
case x : Int => println (x)
}
}
但韓元「T編譯
你可以做這樣的事情(沒有經過測試):
class ActorB extends Actor with ActorLogging {
def receive = {
case x : Int => context.become(waitingForMore(List(x)))
}
def waitingForMore(xs : List[Int]) : Receive = {
case x : Int if(xs.size == 2) =>
printResults(x :: xs)
context.become(receive)
case x : Int => context.become(waitingForMore(x :: xs))
}
def printResults(xs : List[Int]): Unit = {
// Do printing here.
}
}
在這種模式下,你將採取的事實,演員可以改變自己的內部行爲的優勢。你不會明確地存儲一個Ints列表,而是你將從一個函數傳遞給另一個函數。本質上,演員等待你發送一個Int(receive
方法),然後進入收集更多結果的狀態(waitingForMore
方法)。一旦該方法收集到足夠的數據,它將打印結果並返回到receive
方法中,該方法將重新開始整個過程。
編輯正如所建議的,我只是添加一個小的評論,爲什麼我提出這個模型。我覺得你的演員所處的狀態更清晰地模擬了這一點。隨着問題的增加和變得越來越複雜,這可能是一個很好的模式。或者它可能不會,因爲費利克斯指出這兩種解決方案通過不同的方式得到相同的答案。您絕對應該隨時挑選您感覺更舒適的解決方案。我的目的是展示一個更實用的替代方法,就是這些。
你可以做這樣的事情:
class ActorB extends Actor with ActorLogging{
var xs:List[Int] = Nil
def receive = {
case x : Int =>
xs = x :: xs
if(xs.length==3){
println(xs.mkString(" ")+" avg: "+xs.sum/3d)
xs = Nil
}
}
}
(我沒有測試以上,b它應該給你的想法)
我認爲這可能比使用成爲/ unbecome更容易一點。也許你有理由使用這種模式?
如果你打算讓你的actor有狀態,爲什麼不把消息存儲在本地列表中,然後在你的列表包含3個項目時將它們打印出來呢? – Felix
我加了一個答案。有狀態意味着你的價值(你的演員)會隨着「時間」的流逝而表現出不同,也就是說,如果你使用成爲/不成熟,你的演員每次收到一條消息都不會執行相同的動作。在下面的回答中,您將有狀態限制在您的演員所包含的列表中,查看接收情況,它會更清晰地發生什麼,因爲我們以可讀的方式處理列表的狀態。 – Felix