Scala 中的列表和元组

机器人

来自 Martin Odersky 所著的“Scala 编程”一书:

另一个有用的容器对象是元组。与列表一样,元组是不可变的,但与列表不同的是,元组可以包含不同类型的元素。

但我可以:

val oneTwoThreee = List(1, 2, "Third Element") //same as:List.apply(1,2,3)
for (i <- 0 to 2) {
  println(oneTwoThreee.apply((i)))
}

它的输出是:

1 
2
Third Element

所以 Scala 中的 List 可以有不同类型的元素。

来自同一本书:

您可能想知道为什么不能像列表中的元素一样访问元组的元素,例如,使用“pair(0)”。原因是列表的 apply 方法总是返回相同的类型,但元组的每个元素可能是不同的类型:

但是如上代码所示, List.apply() 可以返回不同的类型。

我在这里遗漏了有关 Scala 中的列表和元组的内容吗?

尤瓦尔·伊茨恰科夫

我在这里遗漏了有关 Scala 中的列表和元组的内容吗?

我认为 Odersky 试图表明的主要观点是每个元组元素都可以包含自己的单独类型,这允许使用多种不同的类型。aList不能做的事情,因为列表是同构的,这意味着如果你想要 a List[Int],该列表的所有元素都必须是Int值。

如果查看您创建的列表的类型,您将看到编译器推断List[Any],这是所有 Scala 类型的通用超类型。这意味着,如果你想对列表中的元素之一做一些具体的事情,即它是 type 的 head 元素Int,你不能因为编译器知道该元素的所有内容是它的 type Any,而你需要了解如何提取底层的“具体”类型:

scala> val oneTwoThreee = List(1,2,"Third Element")
oneTwoThreee: List[Any] = List(1, 2, Third Element)

使用 a 时Tuple3[Int, Int, String],实际上“保留”了具体类型:

scala> val tup = (1, 2, "Third Element")
tup: (Int, Int, String) = (1,2,Third Element)

现在,如果我们想提取其中一个Int值并将它们加 1,我们可以:

scala> tup.copy(tup._1 + 1)
res1: (Int, Int, String) = (2,2,Third Element)

如果我们尝试对 a 做同样的事情List[Any],编译器会理所当然地抱怨:

scala> oneTwoThreee.head + 1
<console>:13: error: type mismatch;
 found   : Int(1)
 required: String
       oneTwoThreee.head + 1
                           ^

该错误有些误导,但发生这种情况是因为实际上head是 类型Any

使用shapeless和它的HList数据类型可以更高级地使用异构列表

import shapeless._

object Tests {
  def main(args: Array[String]): Unit = {
    val hList = 1 :: 2 :: "Third" :: HNil

    println(hList.head + 1)
  }
}

其中产生:

2

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章