理解 Scala ->句法 [英] Understanding Scala -> syntax

查看:56
本文介绍了理解 Scala ->句法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过 artimaScala 编程"一书了解 Scala.>

在介绍 Map 特征的同时,作者不遗余力地将 -> 语法描述为一种可以应用于任何类型以获取元组的方法.

事实上:

scala>(2->两个")res1: (Int, String) = (2,two)标度>(2,两个")res2: (Int, String) = (2,two)标度>(2->"二") == (2, "二")res3:布尔值 = 真

但这些并不等价:

scala>映射(1->一")+(2->二")res4: scala.collection.immutable.Map[Int,String] = Map(1 -> 一, 2 -> 二)标度>映射(1->一")+(2,二")<console>:8: 错误:类型不匹配;发现:整数(2)要求:(整数,?)映射(1->一")+(2,二")

为什么会这样,因为我的第一次测试似乎表明两种pair"语法都构建了一个元组?

问候.

解决方案

完全一样,感谢Predef中的这个类(这里只复制了一部分):

final class ArrowAssoc[A](val __leftOfArrow: A) extends AnyVal {@inline def ->[B](y: B): Tuple2[A, B] = Tuple2(__leftOfArrow, y)}@inline 隐式 def any2ArrowAssoc[A](x: A): ArrowAssoc[A] = new ArrowAssoc(x)

那么现在的问题是 (a,b) 语法何时会模糊,而 (a -> b) 不会?答案就在函数调用中,尤其是当它们被重载时:

def f[A](a: A) = a.toStringdef f[A,B](a: A, b: B) = a.hashCode + b.hashCodef(1,2)//整数 = 3f(1 -> 2)//字符串 = (1,2)f((1, 2))//字符串 = (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 代替键值对.

I am getting a taste of Scala through the artima "Programming in Scala" book.

While presenting the Map traits, the authors go to some lengths to describe the -> syntax as a method that can be applied to any type to get a tuple.

And indeed:

scala> (2->"two")
res1: (Int, String) = (2,two)

scala> (2,"two")
res2: (Int, String) = (2,two)

scala> (2->"two") == (2, "two")
res3: Boolean = true

But those are not equivalent:

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")

Why is this so, since my first tests seem to show that both "pair" syntaxes build a tuple?

Regards.

解决方案

They are exactly the same, thanks to this class in Predef (only partly reproduced here):

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)

So now the question is when will (a,b) syntax be ambiguous where (a -> b) is not? And the answer is in function calls, especially when they're overloaded:

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 + in particular gets confused because it's overloaded with a multiple-argument version, so you could

Map(1 -> 2) + (3 -> 4, 4 -> 5, 5 -> 6)

and it thus interprets

Map(1 -> 2) + (3, 4)

as trying to add both 3 to the map, and then 4 to the map. Which of course makes no sense, but it doesn't try the other interpretation.

With -> there is no such ambiguity.

However, you can't

Map(1 -> 2) + 3 -> 4

because + and - have the same precedence. Thus it is interpreted as

(Map(1 -> 2) + 3) -> 4

which again fails because you're trying to add 3 in place of a key-value pair.

这篇关于理解 Scala ->句法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆