由於sepp2k
在他的評論中已經提到,符號Map
指的是Map
的伴侶對象,它允許您訪問其單個實例。在圖案匹配,這是經常被用來識別一個信息:如果你寫Map()
您將調用對象Map
的apply
方法
scala> case object Foo
defined module Foo
scala> def send[A](a: A) = a match { case Foo => "got a Foo" case Map => "got a Map" }
send: [A](a: A)String
scala> send(Map)
res8: String = got a Map
scala> send(Foo)
res9: String = got a Foo
。由於您沒有給出任何值來插入到Map
編譯器不能推斷任何類型,因此它必須使用bottom type - Nothing
- 這是每種類型的子類型。這是唯一可能的類型來推斷哪些不會破壞類型系統,儘管存在差異。將Nothing
不存在下面的代碼將無法編譯:
scala> Map(1 -> 1) ++ Map()
res10: scala.collection.mutable.Map[Int,Int] = Map(1 -> 1)
如果你看看到的++
類型簽名是如下(source)
def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): Map[A, B1]
你會發現下限鍵入參數B1 >: B
。因爲Nothing
是一切的子類型(在我們的例子中爲B
),編譯器可以找到一個B1
(在我們的例子中爲Int
)併成功推斷出我們的Map的類型簽名。此結合的下需要因爲B
是協變(source)
trait MapLike[A, +B, ...] ...
這意味着我們不能讀出它作爲方法參數(因爲方法參數在逆變位置)。如果方法參數不在逆向位置Liskov's substitution principle將不再由類型系統保存。因此必須找到代碼來編譯一個新類型(這裏稱爲B1
)。
由於Didier Dupont
已經指出Scaladoc 2.9中存在一些bug,這些bug在2.10中解決。不僅有一些錯過的方法顯示在那裏,而且還可以顯示通過隱式轉換添加的方法(例如,在2.10中顯示很多方法,但不顯示在2.9中)。
只要編寫'Map'不會調用'apply'方法 - 它只是指類型。因此'Map'編譯並不奇怪。真正的問題是爲什麼當你編寫Map()時它仍然會編譯。 – sepp2k 2012-07-21 16:17:28
@ sepp2k謝謝,我更新了這個問題。 – 2012-07-21 16:21:33