我有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