2012-08-17 55 views
1

我定義了下面的類斯卡拉 - Scalaz unMkIdentity NullPointerException異常

private sealed trait Action2[-T1, +R] extends Function1[T1, R] { 
    def printResults() 
} 

private abstract class BaseAction[T1, R] extends Action2[T1, R]{ 
    protected var result: R = null 

    override final def apply(values: T1) : R = { 
    result = evaluate(values) 
    result 
    } 

    override final def printResults() { 
    if(result == null) 
     print("The results have not been evaluated!") 
    else 
     printLazyResults(result) 
    } 

    protected[this] def printLazyResults(results: R) 
    protected[this] def evaluate(values: T1) : R 
} 

我有這個類的實現,每當我嘗試實例給定的實施方法:

implicit def unMkIdentity[A](x: Identity[A]): A = x.value 

拋出空指針異常。我首先不明白爲什麼叫(我導入scalaz和Scalaz)以及它爲什麼從屬性結果中得到一個空值...

+1

您能否提供實際拋出異常的代碼?或者將其剝離爲一個最小的例子? – drexin 2012-08-17 10:32:35

回答

2

通常你會遇到像class X[R] { var r: R = null }這樣的定義:

scala> class X[R] { var r: R = null } 
<console>:7: error: type mismatch; 
found : Null(null) 
required: A 
     class X[R] { var r: R = null } 

在這種情況下,一個奇怪的現象正在發生的事情,讓你的代碼編譯:編譯器看到,它在unMkIdentity一個隱含Identity[R] => R,所以它解釋nullIdentity[R]一個實例,並試圖使轉換,這當然不起作用。

這不是預期的行爲 - 這只是一個很大的謊言周圍一個奇怪的小結果。

在任何情況下,你都不應該編寫var r: R = null來初始化一個成員變量 - 你應該總是使用var r: R = _,它會選擇一個合適的默認值。有關更多信息,請參閱the language specification的第4.2節(「變量聲明和定義」)。