空值是所有引用類型的一個子類型;
所以理論上,在這個例子中,我們可以假設Null
是Foo
(引用類型)的子類型,我們應該能夠嘗試調用bar
方法上Null
類型的實例。實際上,我們不能在編譯時錯誤代碼片段,錯誤號爲value bar is not a member of Null
。
case class Foo(bar: String)
val n: Null = null
n.bar
我認爲這讓我們抓住這個在編譯時有道理的,因爲作爲斯卡拉文檔也say[Null's] only instance is the null reference
,但我認爲更準確的錯誤消息將是Calling bar on type Null can only result in a NullPointerException
。
我的問題是關於下面的代碼段,這並不在編譯時失敗,而是在運行時失敗了NullPointerException
val n: Null = null
n.toString
我假設這是因爲Null類型並不是真正的子類化其他所有引用類型,只有子類AnyRef
,但是有什麼理由說明這個sh不會拋出編譯時錯誤(或至少警告),該代碼只能導致NullPointerException
?是否故意撥打null.bar
和null.toString
表現不同?
但肯定這兩個說法有衝突嗎?在[this]中(http://www.cmi.ac.in/~madhavan/courses/pl2009/lecturenotes/lecture-notes/node28.html)子類型的定義如果每個函數都可以使用,則類型B是A的子類型在A類型的對象上調用也可以在類型爲B的對象上調用。如果我的例子中,如果不能在類型爲'Null'時調用'.bar',那麼輸入'Null'不是'Bar'子類型。 – theon
嗯,我不確定,但它似乎像這個表達式('val n:Foo = null')翻譯成類似於「讓Null'成爲'Foo'的子類型」,所以'val n:空=空轉換爲一個簡單的'空'。考慮兩個類 - 'Foo(bar:String)'和'Bar(foo:String)'。在這種情況下,如果你寫'val n:Null = null'它應該是哪個子類型? – serejja
它應該是'Foo'和'Bar'的子類型,但這是一個好點;多個類繼承在scala中是不可能的,所以它不可能。我一直在查看子類型和繼承,但也許他們需要在Scala中被認爲是不同的東西。 – theon