2012-07-21 81 views
3
C:\Users\John>scala 
Welcome to Scala version 2.9.2 (Java HotSpot(TM) Client VM, Java 1.6.0_32). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> import scala.collection.mutable.Map 
import scala.collection.mutable.Map 

scala> Map() 
res4: scala.collection.mutable.Map[Nothing,Nothing] = Map() 

當使用Map()而不使用關鍵字new時,將從相應伴隨對象調用apply方法。但Scala文檔沒有列出可變映射的apply方法(只提供了一個apply方法從地圖中檢索值)。爲什麼不使用apply方法可以創建Map對象?

爲什麼上面的代碼仍然有效?

+2

只要編寫'Map'不會調用'apply'方法 - 它只是指類型。因此'Map'編譯並不奇怪。真正的問題是爲什麼當你編寫Map()時它仍然會編譯。 – sepp2k 2012-07-21 16:17:28

+0

@ sepp2k謝謝,我更新了這個問題。 – 2012-07-21 16:21:33

回答

5

它看起來像scaladoc中的一個bug。有apply方法在對象collection.mutable.Map(從GenMapFactory繼承),但它不出現在文檔的地圖。這個問題似乎在the doc for upcomping 2.10中得到解決。

注意:您必須查看對象文檔,而不是第一類。 class中的apply方法當然適用於現有的地圖實例,並從中檢索數據。

3

scala.collection.immutable.Map()的伴隨對象有apply()方法。它從scala.collection.MapFactory繼承。該方法採用可變數量的自變量對,通常用作

Map("foo"->3, "bar"->4, "barangus"->5) 

不帶任何參數顯然作品,以及調用它,但有人亮度比我必須解釋爲什麼類型推理引擎來了scala.collection.mutable.Map[Nothing,Nothing]爲了它。

1

由於sepp2k在他的評論中已經提到,符號Map指的是Map的伴侶對象,它允許您訪問其單個實例。在圖案匹配,這是經常被用來識別一個信息:如果你寫Map()您將調用對象Mapapply方法

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中)。

相關問題