了解Scala->;语法

了解Scala->;语法,scala,scala-collections,scala-2.10,Scala,Scala Collections,Scala 2.10,我通过artima的“书”尝到了Scala的味道 在介绍映射特征的同时,作者详细描述了->语法,将其作为一种方法,可以应用于任何类型以获得元组 事实上: scala> (2->"two") res1: (Int, String) = (2,two) scala> (2,"two") res2: (Int, String) = (2,two) scala> (2->"two") == (2, "two") res3: Boolean = true 但这些并不等同

我通过artima的“书”尝到了Scala的味道

在介绍
映射
特征的同时,作者详细描述了
->
语法,将其作为一种方法,可以应用于任何类型以获得元组

事实上:

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")
scala>Map(1->“一”)+(2->“二”)
res4:scala.collection.immutable.Map[Int,String]=Map(1->one,2->two)
scala>Map(1->“一”)+(2,“二”)
:8:错误:类型不匹配;
发现:Int(2)
必填项:(Int,?)
地图(1->“一”)+(2,“二”)
为什么会这样,因为我的第一次测试似乎显示两个“成对”语法都构建了一个元组


问候。

由于
Predef
中的这个类,它们完全相同(此处仅部分复制):

所以现在的问题是,
(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
+
尤其容易混淆,因为它使用多参数版本重载,所以您可以

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
来代替键值对。

事实上,它们是等价的:(2->“two”)类似于((2,“two”),
Map(1->“one”)+((2,“two”)
工作得很好<代码>地图(1->“一”)+2->“二”的错误与
地图(1->“一”)+(2,“二”)的错误不一样,你能把这句话重述一遍,让我接受吗?:)你可以接受雷克斯的回答,不过最好能说明为什么
map+2->“两个”
不起作用(不幸的是,我不知道)。@om-nom-nom-嗯,我确实知道那个。@om-nom-nom
map+2->“两个”
会给你
(map+2)->“两个”
+
->
具有相同的优先级,并且是左关联的。感谢您解释为什么需要paren,正如@om nom nom建议的那样。
(Map(1 -> 2) + 3) -> 4