在actor类中引用外部val

时间:2014-10-12 14:31:27

标签: scala closures akka

是否被设计禁止或我做错了什么?

val ext = 1

class Test extends Actor {
  def receive = { case _ => println(ext) }
}

try {
  val sys = ActorSystem("lol")
  sys.actorOf(Props[Test], "test") ! true
} catch {
  case e: Throwable => println(e)
}  

我向Test发送邮件后,我收到例外java.lang.IllegalArgumentException: no matching constructor found on class HelloAkkaScala$Test$1 for arguments [] 如果我没有在ext课程内引用Test,我就不会遇到此例外情况。
我使用的是Akka 2.3.4

1 个答案:

答案 0 :(得分:2)

访问演员之外定义的val(不是var或任何其他可变状态)没有错。

试图在Akka 2.3.5中运行您的示例代码,它运行正常。您的原始代码中可能有拼写错误。

<强>更新

仔细观察你得到的错误,似乎你已经在其他类中定义了Test类。

在这种情况下,内部类Test)将在幕后接收对外部类的引用,以便能够关闭它的成员({ {1}})。

这也意味着内部类的构造函数将引用外部类(语法糖隐藏了这个)。

这也解释了为什么你得到错误(你将0 args传递给构造函数,但实际上有一些你没有提供的隐藏)。

以下是重现此内容的示例:

ext

...这里有一个快速的解决方法(在这种情况下,我将class Boot { val ext = 1 class Test extends Actor { def receive = { case _ => println(ext) } } try { val sys = ActorSystem("lol") sys.actorOf(Props[Test], "test") ! true } catch { case e: Throwable => println(e) } } object Boot extends App { new Boot } Test“静态”移动到伴随对象,但您可以通过引用{{1}来获得类似的结果作为其他实例的成员,传递给构造函数):

ext