Skip to content

Latest commit

 

History

History
67 lines (48 loc) · 2.19 KB

5.4 Tuple.md

File metadata and controls

67 lines (48 loc) · 2.19 KB

Tuple

元组是Scala3中的一种非常重要的内置类型,也是标准库提供的通用数据结构里,唯一有特殊语法地位的类型,这主要是由于,元组和函数的参数列表,以及和样例类,都是同构的,也就是说,它们可以进行互相转换,元组也是Scala3类型编程的重要基石。

在Scala3中,我们这样来构建一个元组:

// scala
val tup0 = EmptyTuple
val tup1 = Tuple1(1)
val tup2: (Int, String) = (1, "x")
val tup3: (Int, String, Int) = (1, "x", 1)
...

二元以上的元组,拥有“字面量”,使用小括号包裹,使用逗号隔开多个值。并且其类型也拥有同样的简写形式。

我们可以使用apply来下标访问:

// scala
val v1 = tup2(0)
val v2 = tup2(1)
val v3 = tup2(2) // 编译错误

如果下标出现越界,将产生一个编译错误。

你可能会好奇这是如何实现的,这当然也不是内置在编译器里面的检查,而是通过类型编程手段在标准库层面完成的。以后我们也会介绍如何编写这样的类型检查。

另外,如果你注意观察的话,会发现,元组的结构和列表很像,只不过它的每一个元素可以是不同类型,并且长度在编译期固定,实际上,元组也是可以像列表一样递归构建的:

// scala
val tup0 = EmptyTuple
val tup1 = 1 *: EmptyTuple
val tup2 = 1 *: "x" *: EmptyTuple
val tup3 = 1 *: "x" *: 1 *: EmptyTuple
...

冒号作为方法名结尾的性质已经多次提到过,不再赘述,这里之所以使用星号,是由于元组也是一种“积类型”(如果你忘记积类型的含义,请回顾ADT部分),所以使用乘法符号。

另外,元组和参数列表也是同构的,比如我们有这样一个接收二元组的函数:

// scala
def f(x: (Int, String)) = println(x)

调用的时候大可不必写成:

// scala
f((1, "x"))

而是可以写成:

// scala
f(1, "x")

别小看这一对括号的差异,实际上这可以说明元组的性质。

元组也是Scala3类型编程的基石,如果你日后想深入Scala3的类型编程,那么一定要对元组有足够的了解。