2013-03-24 76 views
1

Scala REPL爲這兩個表達式提供了相同的類型 - (元組? - 奇怪!)。然而("a" ->1)這是我可以添加到地圖和("a", 1)不能。爲什麼Scala REPL顯示Map表達式的元組類型?爲什麼Scala REPL顯示Map表達式的元組類型?

scala> :t ("a" -> 1) 
(String, Int) 

scala> :t ("a",1) 
(String, Int) 

scala> val m = Map.empty[String, Int] 
m: scala.collection.immutable.Map[String,Int] = Map() 

scala> m + ("a",1) 
<console>:9: error: type mismatch; 
found : String("a") 
required: (String, ?) 
      m + ("a",1) 
     ^

scala> m + ("a" ->1) 
res19: scala.collection.immutable.Map[String,Int] = Map(a -> 1) 

回答

2

實際上,這樣做的原因是,PREDEF:http://www.scala-lang.org/api/current/index.html#scala.Predef$(總是在Scala中範圍)包含從任意給ArrowAssoc(該方法implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A])的隱式轉換

ArrowAssoc包含方法 - >將其轉換爲元組。

所以基本上你在做any2ArrowAssoc("a").->(1),它返回(「a」,1)。

從REPL:

any2ArrowAssoc("a").->(1) 
res1: (java.lang.String, Int) = (a,1) 

此外,還可以在不變的包含HashMap的工作是這樣的:

val x = HashMap[Int,String](1 -> "One") 
x: scala.collection.immutable.HashMap[Int,String] = Map((1,One)) 
val y = x ++ HashMap[Int,String](2 -> "Two") 
y: scala.collection.immutable.Map[Int,String] = Map((1,One), (2,Two)) 
val z = x + (3 -> "Three") 
z: scala.collection.immutable.HashMap[Int,String] = Map((1,One), (3,Three)) 
3

斯卡拉認爲a + (b,c)意味着你試圖調用+方法有兩個參數,這是一種現實的可能性,因爲地圖有一個多參數添加方法,所以你可以做這樣的事情

m + (("a" -> 1), ("b" -> 2)) 

解決方法很簡單:只需添加一組額外的圓括號,因此顯然(b,c)實際上是作爲單個參數傳遞的元組。

m + (("a", 1)) 
+0

謝謝,我得到了你的解釋有關添加元組!問題的另一部分仍然存在 - 關於將地圖添加到地圖。我理解寫表達式'(「a」 - > 1)'有一個Map類型嗎?此外,我無法在Map文檔中找到用於添加地圖的方法的定義。實際上,doc只有兩個用於添加元組的'+'方法:'def +(kvs:(A,B)*):Map [A​​,B] [用例]將鍵/值對添加到此映射中,返回一張新地圖。 abstract def +(kv:(A,B)):地圖[A,B] [用例]在此地圖上添加一個鍵/值對,返回一個新地圖。' – 2013-03-24 20:06:39

+0

查看我的答案: ) – Felix 2013-03-24 20:16:43

+0

雷克斯克爾,@費利克斯,感謝你的偉大解釋!我學習Scala的越多,我就越失望((看起來Scala是「最驚喜」的語言,而不是「最少吃驚」的語言)。我學習Scala越多,我越看重Haskell的美麗和清晰! – 2013-03-24 20:36:18