簡體   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