我必须编写一个代码,使得Actor A生成一个Actor B消耗的无限数字流。 Actor A输出序列:x,f(x),g(f(x))等,其中f(x)= 10(如果x为0),否则为3x,其中g(x)为x / 2。即:
输出:x = 0,f(x)= 10,g(f(x)= 5(3条消息),接着3条消息应为f(g(f(x)),g(f(g(g) f(x))),f(g(f(g(f(x))))及其值......每次内部函数变为x时,计算相邻结果的结果
演员B一次处理数字3,它应该打印同一行中列出的每个三元组与3个数字的平均值。
值(0)从main方法传递给ActorA。
我的尝试:
import akka.actor._
class ActorA(processB:ActorRef) extends Actor with ActorLogging{
def f(x : Int) = if(x == 0) 10 else 3 * x
def g(x : Int) = x / 2
def receive = {
case 0 =>
val x = 0
//processB ! (x)
// processB ! (f(x))
// processB ! (g(f(x)))
println( (f(x)))
println((g(f(x))))
/*case Stop =>
Console.println("Stop")
processB ! Stop
context stop self */
}
}
class ActorB extends Actor with ActorLogging{
def receive = {
case ActorA =>
case Stop =>
Console.println("Stop")
exit()
}
}
case object ActorA
case object ActorB
case object Stop
object messages {
def main(args: Array[String]) :Unit = {
val system = ActorSystem("actors")
val processB = system.actorOf(Props[ActorB])
val actorA = system.actorOf(Props(new ActorA(processB)))
actorA ! 0
}
}
如何制作INFINITE数量的消息,我可以一次处理3个消息吗?感谢
答案 0 :(得分:2)
要获得无限序列,您可以使用Stream。
Derek Wyatt有一篇关于它们的博客文章,以及如何生成Fibonacci数字:
http://www.derekwyatt.org/2011/07/29/understanding-scala-streams-through-fibonacci/
您可以对序列使用相同的基本原理,如果我理解正确,则可以在流中的前一个值上交替应用f和g函数。
你可以写如下:
lazy val stream: Stream[Int] = x #:: stream.zipWithIndex.map {
case (p,i) => if (i%2 == 0) f(p) else g(p)
}
然后,您可以使用grouped
将流拆分为3个块,
在这里,我已经完成了这一点,然后将结果Stream[Int]
(每个大小为3)转换为元组,以方便使用:
val chunks: Iterator[(Int,Int,Int)] = stream.grouped(3).map { s =>
(s.head, s.tail.head, s.tail.tail.head)
}
然后你可以随意使用它,如果你愿意,可以将元组发送给另一个演员。
在另一方面,您可以按如下方式匹配该元组:
case (a:Int, b:Int, c:Int) => ...
答案 1 :(得分:1)
演员的收件箱会填满,并且没有固有的背压来告诉制作人等待。请参阅:How to use Akka BoundedMailBox to throttle a producer
一般情况下,您可能希望B
明确向A
发送要求提供数据的邮件。