如何在ServiceA
和ServiceB
中使我的ActorSystem可用,这是我试图开始工作的代码。它编译但我得到Tcp中隐式系统的空指针异常。
为什么我会得到一个nullpointer异常,我可以改变什么来获取我的 系统进入我的特质服务?为什么要编译?
trait ServiceA {
implicit val system: ActorSystem
}
trait ServiceB {
implicit val system: ActorSystem
Tcp().outgo... // Code compile but i get nullpointer exception
}
object Main extends App with ServiceA with ServiceB {
override implicit val system: ActorSystem = ActorSystem("MySys")
}
答案 0 :(得分:4)
SystemA
和SystemB
(使用system
)的构造函数在Main
的构造函数之前执行,其中包含system
的初始化。在implicit lazy val system = ...
中使用Main
(允许以这种方式实现抽象val
)并且应该修复此问题。
答案 1 :(得分:0)
作为回答的补充
通过@alexei_romanov。
将WriteString("Token:");
调用放入特征体而不将其分配给Tcp...
或val
,您希望实现什么目标?现在只是在def
初始化期间的某个时刻执行的操作。它可以导致未定义的行为,因为它是对尚未初始化的对象的操作。
答案 2 :(得分:0)
这是由特征初始化顺序引起的,确实很遗憾类型系统无法抵御这种情况。
解决此问题的一个选择是将ActorSystem初始化放入其自己的特征中,并确保首先将其混合,因此:
trait ServiceA {
implicit val system: ActorSystem
}
trait ServiceB {
implicit val system: ActorSystem
Tcp().outgo... // Code compile but i get nullpointer exception
}
trait ActorSystemInitialization {
val system: ActorSystem = ActorSystem("MySys")
}
object Main extends App with ActorSystemInitialization with ServiceA with ServiceB {
}