Seq 的用法与 List、Array 和 Vector 的用法相比如何?

How does usage of Seq compare to that of List, Array and Vector?

在SO,我看到比较Array with Seq, List with Seq and Vector with well, everything的问题。我不明白一件事。我什么时候应该对这些中的任何一个使用 Seq ?我了解何时使用 List、何时使用 Array 以及何时使用 Vector。但是什么时候使用 Seq 而不是上面列出的任何集合是个好主意?为什么我应该使用扩展 Iterabletrait 而不是上面列出的所有具体 类?

您通常应该使用 Seq 作为方法的输入参数或 class,通常为序列定义(只是一般,不一定与通用):

def mySort[T](seq: Seq[T]) = ...
case class Wrapper[T](seq: Seq[T]) 
implicit class RichSeq[T](seq: Seq[T]) { def mySort = ...}

现在您可以将任何序列(如 VectorList)传递给 mySort

如果您的算法关心复杂性 - 您可以将其具体化为 IndexedSeq(快速随机元素访问)或 LinearSeq(快速内存分配)。无论如何,如果您希望您的函数在其输入参数上具有更多 polymorphic,您应该更喜欢最顶级的 class,因为 Seq 是所有序列的通用接口。如果您需要更通用的东西 - 您可以使用 TraversableIterable.

这里的原则与许多语言中的原则相同(例如在Java中应该经常使用 List 而不是 ArrayList,或者 Map 而不是 HashMap)。如果你能处理更抽象的 Seq 概念,你应该,尤其是当它们是方法的参数时。

想到的 2 个主要原因:

1) 重用您的代码。例如如果你有一个接受 foo(s:Seq) 的方法,它可以重复用于列表和数组。

2) 轻松改变主意的能力。例如。如果您认为 List 运行良好,但突然意识到您需要随机访问,并想将其更改为 Array,如果您一直在各处定义 List,您将被迫在各处更改它。

注意 #1:如果您的方法支持,有时您可以说 Iterable over Seq,在这种情况下,我倾向于尽可能抽象。

注意#2:有时,我可能倾向于不在我的工作库中说 Seq(或者完全抽象),即使我可以。例如。如果我要用错误的集合做一些非常低效的事情。比如做随机访问——即使我可以编写我的代码来处理列表,也会导致效率低下。