Scala – 使用App trait进行多重继承
发布时间:2020-12-16 18:34:44 所属栏目:安全 来源:网络整理
导读:考虑两个特征,TestTrait1和TestTrait,并假设NewObject扩展两者. 我们的想法是在TestTrait中使用TestTrait1中的变量.以下代码完美无缺. scala trait TestTrait1 { | val arguments1: Array[String] = Array("1","2") | }defined trait TestTrait1scala trait
考虑两个特征,TestTrait1和TestTrait,并假设NewObject扩展两者.
我们的想法是在TestTrait中使用TestTrait1中的变量.以下代码完美无缺. scala> trait TestTrait1 { | val arguments1: Array[String] = Array("1","2") | } defined trait TestTrait1 scala> trait TestTrait { | val arguments: Array[String] | val len = arguments.length | } defined trait TestTrait scala> object NewObject extends TestTrait1 with TestTrait { | lazy val arguments = arguments1 | } defined object NewObject scala> NewObject res30: NewObject.type = NewObject$@7c013560 现在用App替换TestTrait1.由于参数设置为延迟评估,我将假设即使在DelayedInit的情况下,下面的代码也可以工作. scala> object NewObject extends App with TestTrait { | lazy val arguments = args | } 但事实并非如此.这背后的原因是什么? scala> NewObject java.lang.NullPointerException at TestTrait$class.$init$(<console>:12) ... 35 elided 如果是这种情况,在这里使用类似于TestTrait的另一个特征中使用args的解决方案是什么? 解决方法trait TestTrait1 { val arguments1: Array[String] = Array("1","2") } trait TestTrait { val arguments: Array[String] val len = arguments.length } 如果你看到差异,TestTrait有一个成员len,将急切地初始化.但是args是一个def内部应用程序,其默认值为null.如果你将len更改为lazy val或def,它将不会爆炸NPE. 让我们在快速的REPL会话中尝试这个: scala> :paste // Entering paste mode (ctrl-D to finish) trait TestTrait { def arguments: Array[String] lazy val len = arguments.length } object NewObject extends App with TestTrait { override lazy val arguments = super.args // Added `override` and `super` just for clarity. } // Exiting paste mode,now interpreting. defined trait TestTrait defined object NewObject scala> NewObject res0: NewObject.type = NewObject$@5ace1ed4 scala> NewObject.arguments res1: Array[String] = null 如果要重现问题,可以按以下方式调用len: scala> NewObject.len java.lang.NullPointerException at TestTrait$class.len(<console>:12) at NewObject$.len$lzycompute(<console>:15) at NewObject$.len(<console>:15) ... 33 elided 所以,你的问题的答案是,如果你想调用NewObject的实例,你需要使len lazy val或def.我建议将NewObject作为一个类或特性,因为你不希望一个不安全/急切初始化的len成员会爆炸NPE. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |