2010-01-08 48 views
6

我不明白爲什麼下面的情況不匹配。 Null應該是Any的一個實例,但它不匹配。有人可以解釋發生了什麼嗎?匹配元組爲null

val x = (2, null) 
x match { 
    case (i:Int, v:Any) => println("got tuple %s: %s".format(i, v)) 
    case _ => println("catch all") 
} 

prints catch all 

謝謝。

回答

9

這與指定完全相同。

Type patterns consist of types, type variables, and wildcards. 
A type pattern T is of one of the following forms: 

* A reference to a class C, p.C, or T#C. 
This type pattern matches any non-null instance of the given class. 

有趣的是,如此多的相關性歸因於null是Any的成員。它是每種類型的成員,但AnyVal和Nothing。

+0

我認爲這個選擇的動機是它匹配JVM上「instanceof」字節碼的行爲。 – 2010-01-08 17:09:47

+0

那,並讓null通過將完全吸吮。你必須有一個淫穢的零容忍去尋找動機! – extempore 2010-01-08 23:11:13

+0

「Obscene null tolerance」或者沒有,有一種說法是,類型模式「x:T」的最自然和直接的含義是匹配類型T的任何成員。例如,它可以避免像「val x:Any = null「 - 很好,但是」val(x:Any,y:Any)=(null,null)「 - MatchError。這「完全吸引」了。 我並不是說Scala做出了錯誤的選擇,也沒有說它是特別重要的,因爲慣用的Scala避免使用null。 – 2010-01-09 09:08:08

1

我只是猜測在這裏,因爲我不是Scala專家,但根據的任何類在斯卡拉我認爲,因爲null不是一個對象,它不是來自任何和作爲這與列出的第一種情況不符。

添加下面的代碼示例。它在運行時打印「別的東西」。

val x = (2, null) 
x match { 
    case (i:Int, v:Any) => println("got tuple %s: %s".format(i, v)) 
    case (i:Int, null) => println("something else %s".format(i)) 
    case _ => println("catch all") 
} 

進一步的研究之後,好像空應與任何意義匹配documentation說,它擴展AnyRef延伸的任何。

編輯:像其他人一樣說。第一個案件的目的不符合null。它在文檔中指定。

+0

'null'是'Null'類的單例實例。 – 2010-01-08 01:46:26

+0

這很有道理。 null的文檔(http://www.scala-lang.org/docu/files/api/scala/Null.html)表示它擴展了擴展Any的AnyRef,所以它看起來應該匹配大小寫(i:Int,五:任何)。 – 2010-01-08 01:50:14

3

即按規定(Scala的參考2.7,8.2節)是:

的引用對類C,P.C,或T#℃。 此類型模式匹配給定類的任何非空實例。 請注意,該類的前綴(如果給出 )與確定類實例的 相關。對於 實例,模式p.C僅匹配 類別C的實例,這些類別是使用路徑p創建的 作爲前綴。

6

您是否嘗試過v佔位什麼

val x = (2, null) 
x match { 
    case (i:Int, v) => println("got tuple %s: %s".format(i, v)) 
    case _ => println("catch all") 
}