Scala中的列表和元组 [英] List and Tuples in Scala

查看:233
本文介绍了Scala中的列表和元组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

摘自Martin Odersky的《 Scala编程》一书:

From the book 'Programming in Scala' by Martin Odersky:

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

Another useful container object is the tuple. Like lists, tuples are immutable, but unlike lists, tuples can contain different types of elements.

但是我可以拥有:

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可以具有不同类型的元素.

So List in Scala can have different types of elements.

同一本书中的

您可能想知道为什么无法访问元组的元素 类似于列表中的元素,例如,带有"pair(0)".原因 是列表的apply方法总是返回相同的类型,但是每个 元组的元素可能是不同的类型:

You may be wondering why you can’t access the elements of a tuple like the elements of a list, for example, with "pair(0)". The reason is that a list’s apply method always returns the same type, but each element of a tuple may be a different type:

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

But as above code shows, List.apply() can return different types.

我在这里是否缺少有关Scala中的List和Tuple的信息?

Am I missing something here regarding List and Tuples in Scala?

推荐答案

我在这里是否缺少有关Scala中的List和Tuple的信息?

Am I missing something here regarding List and Tuples in Scala?

我认为Odersky试图说明的要点是,每个元组元素可以包含自己的单独类型,从而可以使用多种不同类型. List不能执行的操作,因为列表是同质的,这意味着如果要使用List[Int],则该列表的所有元素都必须为Int值.

I think the main point Odersky is trying to show is that each tuple element can contain its own individual type, which allows using multiple different types. Something that a List can't do because a list is homogeneous, meaning if you want a List[Int], all elements of that list must be Int values.

如果查看创建的列表的类型,您会看到编译器推断List[Any],这是所有Scala类型的通用超类型.这意味着,如果要对列表中的元素之一进行具体处理,即Int类型的head元素,则不能这样做,因为所有编译器都知道该元素是Any,您将需要一些如何提取基础的具体"类型的方法:

If you look at the type of the list you created, you'll see that the compiler infers List[Any], which is the common supertype of all Scala types. This means that if you want to do something concrete with the one of the elements in the list, i.e. it's head element which is of type Int, you can't because all the compiler knows about that element is that its of type Any, and you'll need to some how extract the underlying "concrete" type:

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

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

While using a Tuple3[Int, Int, String], actually "keeps" the concrete types:

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

现在,如果我们要提取Int值之一并将其增加1,我们可以:

Now if we want to extract one of the Int values and increment them by 1, we can:

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

如果我们尝试对List[Any]执行相同操作,则编译器将正确地抱怨:

If we tried doing the same with a List[Any], the compiler would rightfully complain:

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

该错误在某种程度上具有误导性,但这是由于head实际上是Any类型而引起的.

The error is somewhat misleading, but this happens due to the fact head is actually of type Any.

使用无形,它是HList数据类型:

import shapeless._

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

    println(hList.head + 1)
  }
}

哪个产量:

2

这篇关于Scala中的列表和元组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆