为什么变量或变量的变量不同?

时间:2014-11-15 17:02:47

标签: scala akka

我在Scala中使用Akka有一个简单的程序,我有以下场景:我有两种不同的简单演员(FooActorBarActor)。 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)
  }

}

1 个答案:

答案 0 :(得分:6)

答案在于Props.apply方法的签名。

def apply[T <: Actor: ClassTag](creator: ⇒ T): Props = ...

按名称输入参数。这结合了一个事实,即一个actor中的sender()是一个方法而不是一个val,它会带你进入sender()以后某个时候(当评估creator时)被调用的情况处理原始邮件的更多内容,从而将引用返回DeadLetters