我在Scala中使用Akka有一个简单的程序,我有以下场景:我有两种不同的简单演员(FooActor
和BarActor
)。 FooActor
通过构造函数接收ActorRef
,构造函数代表FooActor
应该向其发送答案的某个演员(原始发件人)。此原始发件人由BarActor
提供。我的问题是:为什么不同的是传递构造函数本地sender
并传递一个先前分配有sender
值的局部变量?它们是引用还是在对象中包含引用?引擎盖下发生了什么?谢谢。这是代码:
import akka.actor._
case class foo(x: Int) // some dummy message to test
class FooActor(originalSender: ActorRef) extends Actor {
println("[" + self.path + "] originalSender = " + originalSender) // print the sender
override def receive = {
// (...)
case _ =>
}
}
class BarActor extends Actor {
override def receive = {
case foo(x) =>
// variant 1: this prints deadLetters as the sender in the FooActor
context.actorOf(Props(new FooActor(sender)), "foo" + x)
// variant 2: this prints the original sender correctly
// val originalSender = sender
// context.actorOf(Props(new FooActor(originalSender)), "foo" + x)
case _ =>
}
}
object Main {
def main(args: Array[String]): Unit = {
val system = ActorSystem("my-system")
val sender = system.actorOf(Props[BarActor], "sender") // this would be the original sender
val bar = system.actorOf(Props[BarActor], "bar") // this is the intermediate actor, who passes the sender
bar.tell(foo(1), sender)
}
}
答案 0 :(得分:6)
答案在于Props.apply
方法的签名。
def apply[T <: Actor: ClassTag](creator: ⇒ T): Props = ...
按名称输入参数。这结合了一个事实,即一个actor中的sender()
是一个方法而不是一个val,它会带你进入sender()
以后某个时候(当评估creator
时)被调用的情况处理原始邮件的更多内容,从而将引用返回DeadLetters
。