Seq与List、Array和Vector的使用方式有何区别?

5
在SO上,我看到了一些问题,比较了Array with SeqList with SeqVector with well, everything。但是有一件事情我不太明白。在什么情况下我应该使用Seq而不是这些集合中的任何一个?我知道何时使用List,何时使用Array和何时使用Vector。但是在什么情况下使用Seq而不是上述列出的集合是个好主意呢?为什么要使用扩展Iterabletrait而不是所有上面列出的具体类?

4
可能相关:https://dev59.com/3XRC5IYBdhLWcg3wMd5S这句话的意思是什么? - Gábor Bakos
2个回答

6

通常情况下,您应该将Seq用作方法或类的输入参数,这些方法或类是针对一般序列(仅限一般,不一定具有泛型)定义的:

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(快速内存分配)。无论如何,如果您希望函数在其输入参数上具有更高的多态性,则应优先选择最顶层的类,因为Seq是所有序列的通用接口。如果您需要更通用的内容 - 您可以使用TraversableIterable

1
这里的原则与许多语言相同(例如,在Java中应该经常使用List而不是ArrayList,或者Map而不是HashMap)。如果您能够处理更抽象的Seq概念,尤其是在它们作为方法参数时,就应该这样做。
有两个主要原因:
1)代码重用。例如,如果您有一个接受foo(s:Seq)的方法,它可以重用于列表和数组。
2)轻松改变主意的能力。例如,如果您发现List正在工作良好,但突然意识到需要随机访问,并想将其更改为Array,如果您一直在定义List,则必须强制在所有地方进行更改。
注意#1:有时您可以说Iterable over Seq,如果您的方法支持它,在这种情况下,我倾向于尽可能抽象。
注意#2:有时,即使我可以,我也可能不会在我的工作库中说Seq(或完全抽象化)。例如,如果我要做某些错误集合非常低效的事情。例如进行随机访问-即使我可以编写可以与List一起使用的代码,但这将导致严重的低效率问题。

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