2017-01-04 84 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