简体   繁体   English

Scala特征的隐式Akka系统

[英]implicit Akka system in Scala trait

How can I make my ActorSystem available in ServiceA and ServiceB , this is the code im trying to get get working. 如何使我的ActorSystem在ServiceAServiceB可用,这是我试图开始工作的代码。 It compile but i get a null pointer exception for the implicit system in Tcp . 它可以编译,但是我在Tcp中得到了隐式系统的空指针异常。

Why do I get a nullpointer exception and what can i change to get my system into my trait services? 为什么我会得到一个nullpointer异常,该如何更改才能使系统进入特征服务? Why does it compile? 为什么要编译?

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")
}

Constructors of SystemA and SystemB (which uses system ) are executed before constructor of Main which includes initialization of system . SystemASystemB (使用system )的构造函数在Main构造函数(包括system初始化)之前执行。 Use implicit lazy val system = ... in Main (it is allowed to implement an abstract val in this way) and this problem should be fixed. Main使用implicit lazy val system = ... (允许以这种方式实现抽象val ),此问题应得到解决。

As an addition to answer by @alexei_romanov . 作为@alexei_romanov回答的补充。 What do you want to achieve by placing Tcp... call in a trait body without assigning it to val or def ? 您想通过将Tcp... call放入特征主体而不将其分配给valdef什么? It is now just an action which is executed at some moment during initialization of Main . 现在,这只是在Main初始化期间的某个时刻执行的动作。 It can leat to undefined behavior since it is an action on not yet initialized object. 由于它是对尚未初始化的对象的操作,因此它可能会导致未定义的行为。

This is caused by the trait initialization order, and it is indeed unfortunate that the type system cannot defend against this. 这是由特征初始化顺序引起的,确实不幸的是类型系统无法对此进行防御。

One option to resolve this is to put the ActorSystem initialization into its own trait and make sure that one gets mixed in first, so: 解决此问题的一种方法是将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 {

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM