Scala中Tuple和List[Any]的区别是什么?

7

目前,我正在学习Scala,并阅读这本书 Programming in Scala。书中提到:“与数组或列表不同,元组可以保存不同类型的对象。”例如,以下元组包含Int、String和Float。

val tup = (1, "hello", 4.4)

同样,这本书说,“如果你想在列表/数组中有任何类型的元素,则可以使用任何数据类型。”

val list = List[Any](1, "hello", 4.4)

那么,这两种方法有什么区别?一个优于另一个的好处是什么?

2
“Any”类型通常意味着出现了问题,请避免使用它。 - jwvh
4个回答

13

tup的类型为(Int, String, Double),因此您可以使用正确的类型获取数据:tup._1 的类型是 Intlist的类型是List[Any],因此您失去了所有类型信息:list(0)的类型是Any

除非必须使用Any(或List[Any]等),否则请勿使用它;当元组可行时,千万不要使用它。


感谢您的精确回答。因此,使用List[Any]意味着所有类型信息都将丢失。我会尽可能避免使用Any。谢谢。 - Ra Ka

9

Any 是一个数据类型,类似于 IntString,但与它们不同。
Tuple 是一个容器,可以容纳多种数据类型,即它可以包含不同数据类型的值,但是 Tuple 的类型取决于其中有多少元素,例如:

val tup = (1, "hello", 4.4) // type of tup here is scala.Tuple3 (Int, String, Double)
val tup = (2.3, null) // type of tup here is scala.Tuple2  (Double, Null)
val tup = (5:Any, "hello", 2.2) // type of tup here is scala.Tuple3 (Any, String, Double)

但是,Tuple中每个元素的类型将被保留。另一方面,Any就像一个同质数据类型,在其中没有元素的唯一类型标识,无论是StringInt还是Null类型最初,都将转换为单个数据类型Any并且将失去所有类型信息。
更新: TupleList[Any]之间的区别在于,Tuple可以容纳多种数据类型的元素,仍然保持各个元素的数据类型。而ListArray只能容纳单一数据类型的元素,因此List[Any]将包含所有类型为Any的元素,因此它基本上会将所有元素(不考虑它们先前的数据类型)转换为Any

1
比较的对象是元组和 List[Any](或者 Array[Any] 或者 Seq[Any])之间的区别,并不是元组和 Any` 之间的区别 :) - Alexey Romanov
@AlexeyRomanov,抱歉,我的错。虽然我的回答也可能解释了这个差异,但我会进行编辑。感谢您指出 :) - Shailesh

3

Tuples是类型安全的,而List[Any]则需要将元素强制转换为适当的类型。

val tup = (1, "hello", 4.4)
tup._2 --> gives you string

val list = List[Any](1, "hello", 4.4)
list(1) --> gives you object of type Any and you have to cast this object

你的元组是一个类型为Tuple3[Int, String, Double]的类。


所以,List[Any] 不是类型安全的,如果使用会有类型转换的开销。感谢您的解释。 - Ra Ka
老实说,在大多数情况下,转换的额外开销微不足道,在元组(和大多数泛型使用)生成的代码中编译器也有隐藏的类型转换。类型安全是唯一真正需要关注的问题,但它非常重要。 - Alexey Romanov

-1

我不同意PawelN的观点

val list = List[Any](1, "hello", 4.4)
for (i <- list) println(i.getClass)

或者

val array = Array[Any](1, "hello", 4.4)
for (i <- array) println(i.getClass)

结果为:

class java.lang.Integer
class java.lang.String
class java.lang.Double

因此,访问列表或任意数组中的项时不需要进行转换。当然,如果代码使用这样的东西,我会对其设计感到怀疑。
元组的主要目的是使函数能够返回不同类型的任意数量的对象。这比每次需要返回多个值时创建类轻量得多,但代价是一些类型安全性。

这是错误的@Clem Wang。尝试对列表=List [Any](1,“hello”,4.4)的项目执行一些操作,你会发现它。 - soumya-kole

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接