繁体   English   中英

奇怪的 scala 元组行为

[英]Weird scala tuple behavior

我在 Scala 中注意到了这种行为

val list = List[(Int, Int)]()
val set = HashSet[(Int, Int)]()

scala> list :+ (1, 2)
res30: List[(Int, Int)] = List((1,2))

scala> list :+ (1 -> 2)
res31: List[(Int, Int)] = List((1,2))

scala> list :+ 1 -> 2
res32: List[(Int, Int)] = List((1,2))

//Work
// But the same for set not work
set += (1, 2)
<console>:14: error: type mismatch;
 found   : Int(2)
 required: (Int, Int)
       set += (1, 2)

//Ok may be += in set mean add all that mean this should work
set += ((1, 2))
set += ((1, 2), (3,4))
// Worked

// But why this one work
set += 1 -> 2
set += (1 -> 2)
set += ((1 -> 2))

现在我很困惑,你能解释为什么元组不是元组吗?

scala> (4->5).getClass
res28: Class[_ <: (Int, Int)] = class scala.Tuple2

scala> (4,7).getClass
res29: Class[_ <: (Int, Int)] = class scala.Tuple2$mcII$sp

我认为不同之处在于HashSet[T]+=定义了两个重载,其中一个采用单个T ,另一个采用多个(作为T*参数列表)。 这是从Growable[T]继承的,并在此处显示。

List[T].:+只能在右侧取一个T ,这就是为什么编译器会认为它正在查看一个元组,而不是应该变成一个 params 列表的东西。

如果你set += ((1, 2))那么它编译。 此外, val tuple = (1,2); set += x val tuple = (1,2); set += x也可以。

请参阅 Mario Galic 的答案,了解为什么在HashSet[T].+=的情况下,编译器会选择无法输入的重载而不是可以输入的重载。

解析器阶段-Xprint:parser给出

set.$plus$eq(1, 2)

这似乎解决

def += (elem1: A, elem2: A, elems: A*)

这是一种接受多个 arguments 的方法,因此编译器可能认为elem1 = 1elem2 = 2而不是将(1,2)视为一个元组。

missingfaktor指向SLS 6.12.3 中缀操作作为解释

左结合运算符的右手操作数可能包含几个用括号括起来的 arguments,例如;op;(1,…,)。 然后将该表达式解释为.op(1,…,)。

现在运算符+=是左结合的,因为它不以:结尾,并且+=的右侧操作数由括号(1,2)中的几个 arguments 组成。 因此,根据设计,编译器不会将(1,2)视为Tuple2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM