Scala 在actor类中引用外部val

Scala 在actor类中引用外部val,scala,closures,akka,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发送消息,我就会

是设计禁止还是我做错了什么

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:在类HelloAkkaScala$Test$1上找不到与参数[]匹配的构造函数

如果我没有在
Test
类中引用
ext
,我就没有这个异常。

我使用的是Akka 2.3.4

在访问参与者之外定义的
val
(不是
var
或任何其他可变状态)时没有任何错误

刚刚尝试在Akka 2.3.5中运行示例代码,效果很好。您的原始代码中可能有输入错误

更新

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

在这种情况下,内部类(
Test
)将在后台接收对外部类的引用,以便能够关闭其成员(
ext

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

这也解释了为什么会出现错误(您将0个参数传递给构造函数,但实际上有一些隐藏的参数没有提供)

下面的示例再现了这一点:

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

}
。。。这里有一个快速的解决方法(在本例中,我通过将
测试
ext
移动到伴生对象,使它们成为“静态的”,但您可以通过引用
ext
作为某个其他实例的成员传递给构造函数来获得类似的结果):


查看我答案的更新。
class Boot {

  import Boot.Test

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

}

object Boot extends App {

  val ext = 1

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

  new Boot

}