为什么在 Scala 中使用 Tuple 而不是 Set?

Why to use Tuple over Set in Scala?

两者都可以存储混合类型,但 Set 似乎更强大,因为它具有联合、交集或差异等特征。

另一个重要区别是元组不被视为集合。

我正在学习 Scala,我想知道为什么我要在集合上使用元组。

元组的主要优点是保留了类型信息。这在像 Scala 这样的静态类型语言中是一件大事。

scala> (4.2,'c',true,"blah",7)
res2: (Double, Char, Boolean, String, Int) = (4.2,c,true,blah,7)

scala> Set(4.2,'c',true,"blah",7)
<console>:11: warning: a type was inferred to be `Any`; this may indicate a programming error.
       Set(4.2,'c',true,"blah",7)
           ^
res3: scala.collection.immutable.Set[Any] = Set(true, blah, 7, c, 4.2)

一旦我们的 Set 类型是 Set[Any] 那么我们就丢失了类型信息,这些信息对于避免问题(即错误)可能很有价值。

此外,从 Set[Any] 中提取元素可能会很痛苦。从中提取的每个元素[例如mySet.head] 可能需要在使用前进行类型测试。从元组中获取单个元素也可能相当麻烦 [myTup._3] 但是编译器和您的代码的其余部分确切地知道它得到了什么。

当你需要一个元组时,你不会使用像集合这样的东西。想象一下,编写一个方法,而不是 return 只是一个 Int,例如,您需要 return 两个 Int,或者一个 Int 和一个 String。返回一个 Set[Any] 在那里并没有真正意义,但是 returning 一个 (Int, Int) 或 (Int, String) 在意图方面更具可读性和清晰性。

Set 是可迭代的集合,可以是可变的或不可变的,并且只能采用不同的值。

val set = Set('a','b','b')
println(set)
set.foreach(i => print(i + ", "))

将打印

Set(a,b)
a, b, 

元组是不可变的,它不是一个集合,它不会将元素缩减为不同的值,它会维护元素的类型。如果将 productIterator() 方法应用于元组,它可以是可迭代的。

val tuple = ('a','b','b')
println(tuple)
tuple.productIterator.foreach(i => println(i))

将打印

(a,b,b)
a, b, b,

一个元组有 22 个元素的限制,而 Set 没有这个限制。

val set = Set('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z')
println("set: " + set)

将打印 set: Set(e, s, x, n, j, y, t, u, f, a, m, i, v, q, b, g, l, p, c, h, r, w, k, o, z, d)

集合可以说更健壮,而元组提供了集合(和其他集合)不提供的一些表面级别的灵活性。这是 Set 以外的一些 Scala 集合的图形。

集合和元组之间的一个巨大区别是,集合被视为一个集合,就像我们从 Set Theory 中取出它一样。 Set 可用于有效地相交、并集、差异化以及查看另一组是否是另一组的 subset/superset。集合中的重复元素没有意义,因为可能始终存在元素的表示形式。

A​​ TupleN 简单地表示一个包含 N 个元素的容器,并且不具有这样的 Set 所具有的任何属性。因此,当您想在一个 "bag" 中保存多个项目时,您会想使用它,而当您希望将多个项目作为一个组查看并相应地对其进行操作时,将使用集合。

套数:

  • 必须都是同一类型。
  • 不能包含重复元素。
  • 不保留插入顺序。
  • 可以非常大,大小不等。
  • 有更多类似集合的操作。

元组:

  • 可以包含不同的类型。
  • 可以在编译时验证。
  • 只能包含 22 个元素。
  • 用于保存具有静态大小的临时结果。