2013-08-24 69 views
0

以下是有效的語句斯卡拉:爲什麼我可以將null分配給Option?

scala> var x: Option[Int] = Some(3) 
x: Option[Int] = Some(3) 

scala> var x: Option[Int] = None 
x: Option[Int] = None 

下是無效的:

scala> var x: Option[Int] = 3 
<console>:7: error: type mismatch; 
found : Int(3) 
required: Option[Int] 
     var x: Option[Int] = 3 

到目前爲止,這些例子道理給我; Option [T]類型的值可以是Some [T]或None類型,所以編譯器會阻止您分配一個既不是類型的值。

然而,Scala編譯器似乎接受這一點:

scala> val x: Option[Int] = null 
x: Option[Int] = null 

如果我再嘗試做的選擇(例如下面),我會得到失敗沒想到一個模式匹配 - 爲什麼編譯器不通過拒絕賦值null來保護我?

x match { 
    case Some(y) => println("Number: ", y) 
    case None => println("No number") 
} 
+3

任何引用都可以爲null;這只是在JVM上運行的一個不幸的後果。 –

+0

謝謝克里斯託弗!我剛剛閱讀[這篇文章](http://www.naildrivin5.com/blog/2010/07/30/in-offense-of-scala-option.html),其中說:「當然,這一切都不會拯救你從null開始,因爲Scala非常樂意將null分配給任何東西,這讓整個事情看起來有點無意義。「 有點令人失望;我假定Option(Some/None)匹配模式已經完成,但實際上完成了,我想你需要匹配Some/None/null,並且對從Some獲得的值進行進一步檢查。 –

+3

在進一步閱讀時,我想我理解得更好一點。選項更多的是傳達程序員的_intent_,某種方法可能會返回一個值。如果被調用的代碼行爲良好,調用者不需要明確地處理null,因爲調用者並不期望它。正如[這裏](http://james-iry.blogspot.jp/2010/08/why-scalas-and-haskells-types-will-save.html)所述,「我所知道的所有Scala開發人員的經驗NPE在處理現有的Java庫時大多隻是一個問題,因爲Scala程序員和庫避免了它。「 –

回答

6

如果你看一下Scala class hierarchy,你會看到,從AnyRef派生的類都是Null超類,任何這樣的超級類可分配值null。由於Option就是這樣一個類,你可以給它分配Null

注意,既SomeNone.type(即,None對象的單型)的Null超類,所以null爲任一有效的值。

您不能將3指定爲Option,因爲3不是Option(顯然)的子類的值。

0

這個問題的答案,你可能打算要問的問題是這樣的:

成語斯卡拉將永遠不會使用null。空引用純粹是爲了與Java和其他JVM語言的互操作性而存在。如果您在Scala代碼中看到null,應立即引起審查。你永遠不會錯誤地使用null,所以不需要編譯器警告。正如丹尼爾索布拉爾的回答和評論所指出的,編譯器不能提供針對null的保護。

相關問題