我通过artima“Programming in Scala”书来了解Scala。
在介绍Map
特征时,作者会花一些时间来描述->
语法作为一种方法,可以应用于任何类型来获取元组。
确实:
scala> (2->"two")
res1: (Int, String) = (2,two)
scala> (2,"two")
res2: (Int, String) = (2,two)
scala> (2->"two") == (2, "two")
res3: Boolean = true
但那些并不等同:
scala> Map(1->"one") + (2->"two")
res4: scala.collection.immutable.Map[Int,String] = Map(1 -> one, 2 -> two)
scala> Map(1->"one") + (2, "two")
<console>:8: error: type mismatch;
found : Int(2)
required: (Int, ?)
Map(1->"one") + (2, "two")
为什么会这样,因为我的第一次测试似乎表明两个“pair”语法都构建了一个元组?
问候。
答案 0 :(得分:6)
它们完全相同,感谢Predef
中的这个类(此处仅部分转载):
final class ArrowAssoc[A](val __leftOfArrow: A) extends AnyVal {
@inline def -> [B](y: B): Tuple2[A, B] = Tuple2(__leftOfArrow, y)
}
@inline implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] = new ArrowAssoc(x)
现在的问题是,(a,b)
语法何时不明确(a -> b)
?答案是在函数调用中,特别是在它们被重载时:
def f[A](a: A) = a.toString
def f[A,B](a: A, b: B) = a.hashCode + b.hashCode
f(1,2) // Int = 3
f(1 -> 2) // String = (1,2)
f((1, 2)) // String = (1,2)
地图+
特别容易混淆,因为它超载了多参数版本,所以你可以
Map(1 -> 2) + (3 -> 4, 4 -> 5, 5 -> 6)
因此解释了
Map(1 -> 2) + (3, 4)
尝试将3
添加到地图中,然后4
添加到地图中。这当然没有意义,但它没有尝试其他解释。
->
没有这种歧义。
然而,你不能
Map(1 -> 2) + 3 -> 4
因为+
和-
具有相同的优先级。因此它被解释为
(Map(1 -> 2) + 3) -> 4
再次失败,因为您尝试添加3
代替键值对。