[英]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.