Scala Seq 解包

Scala Seq unpacking

在 Scala 中元组可以解包:

val colors = ("red", "green")
val (colorA, colorB) = colors

Python 还提供了一种解包元组的方法,以及类似的方法来解包列表

colors = ['red', 'green']
(colorA, colorB) = colors

是否有 Scala 序列的等效项?

val colors = Seq("red", "green")
val (colorA, colorB) = colors // Raises a compilation error

如果不能,为什么不能?

scala> val colors = Seq("red", "green")
val colors: Seq[String] = List(red, green)

scala> val Seq(ca, cb) = colors
val ca: String = red
val cb: String = green

还有更多:

Welcome to Scala 3.1.3-RC2 (17.0.3, Java Java HotSpot(TM) 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.

scala> val colors = (1 to 8).map(i => s"c$i")
val colors: IndexedSeq[String] = Vector(c1, c2, c3, c4, c5, c6, c7, c8)

scala> val c1 +: _ = colors // get head
val c1: String = c1

scala> val _ :+ c8 = colors // get last
val c8: String = c8

scala> val head +: _ :+ last = colors
val head: String = c1
val last: String = c8

scala> val _ +: snd +: _ = colors // get second
val snd: String = c2

// note: the following code is for scala3(scala2 should be slightly change)
scala> val Seq(_, c2, _*) = colors // get second too
val c2: String = c2

scala> val init +: tail = colors // split to head and remain
val init: String = c1
val tail: IndexedSeq[String] = Vector(c2, c3, c4, c5, c6, c7, c8)

你需要明白的秘密是这个说法是错误的:

In Scala tuples can be unpacked

Scala 中没有元组解包

相反,值定义可以利用模式匹配,即值定义的left-hand端可以是模式[=39] =].

Section 4.1 Value Declarations and Definitions of the Scala Language Specification:

Value definitions can alternatively have a pattern as left-hand side.

由于您可以模式匹配 Seq,这意味着您可以在值定义期间“解压”它,因为它们是同一事物,并且您使用相同的语法来实现。

但重要的是要了解这是不是“元组解包”或“Seq解包”。这不是一些只适用于少数特殊类型的特殊功能。它只是 bog-standard 模式匹配,因此适用于 每个可以匹配的 ,即每个案例 class、每个提取器对象、每个 class unapplyunapplySeq,每个 class 都有一个构造函数,等等

所以,如果您知道如何模式匹配 Seq,那么您也知道如何“解压”Seq:

val Seq(colorA, colorB) = colors