2017-01-04 80 views
4

考虑两个特性TestTrait1和TestTrait,并假设NewObject扩展了这两个特性。 这个想法是在TestTrait中的TestTrait1中使用变量。下面的代码工作得很好。Scala - 与App特性的多重继承

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 = [email protected] 

现在用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来解决呢?

回答

2
trait TestTrait1 { 
    val arguments1: Array[String] = Array("1","2") 
} 

trait TestTrait { 
    val arguments: Array[String] 
    val len = arguments.length 
} 

如果你看到的不同,TestTrait有一个成员len会急切地得到初始化。但是argsApp内部的def,恰好其默认值为null。如果您将len更改为lazy valdef,则不会因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 = [email protected] 

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 valdef。我建议将NewObject设置为classtrait,因为你不想要一个不安全/急切地初始化的成员,它会与NPE一起爆炸。

+1

感谢您用相同的例子解释这一点。这个解释很有道理。 – rashmina