2013-03-24 48 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

相关问题