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
}