[英]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 = 1
或elem2 = 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.