在SO,我看到了比较Array with Seq,List with Seq和Vector with well, everything的问题。我不明白一件事。我什么时候应该使用Seq
而不是其中任何一个?我了解何时使用List
,何时使用Array
以及何时使用Vector
。但是,何时使用Seq
而不是上面列出的任何集合是个好主意?为什么我应该使用扩展trait
的{{1}}而不是上面列出的所有具体类?
答案 0 :(得分:4)
您通常应该使用Seq作为方法或类的输入参数,一般为序列定义(只是一般的,不一定是通用的):
def mySort[T](seq: Seq[T]) = ...
case class Wrapper[T](seq: Seq[T])
implicit class RichSeq[T](seq: Seq[T]) { def mySort = ...}
现在您可以将任何序列(例如Vector
或List
)传递给mySort
。
如果您的算法关注复杂性 - 您可以将其具体化为IndexedSeq
(快速随机元素访问)或LinearSeq
(快速内存分配)。无论如何,如果您希望函数的输入参数更多polymorphic,则您应该更喜欢大多数顶级类,因为Seq
是所有序列的通用接口。如果您需要更通用的内容,可以使用Traversable
或Iterable
。
答案 1 :(得分:1)
这里的主体与许多语言相同(例如,在Java中应该经常使用List而不是ArrayList,或者使用Map而不是HashMap)。如果你可以处理Seq的更抽象的概念,你应该,特别是当它们是方法的参数时。
浮现在脑海中的两个主要原因:
1)重用您的代码。例如如果你有一个采用foo(s:Seq)的方法,它可以重用于列表和数组。
2)轻松改变主意的能力。例如。如果您认为List运行良好,但突然您意识到您需要随机访问,并希望将其更改为数组,如果您一直在定义List,那么您将被迫在任何地方更改它。
注意#1:有时你可以说Seq上的Iterable,如果你的方法支持它,在这种情况下我倾向于尽可能抽象。
注意#2:有时,我可能倾向于不在工作库中说Seq(或完全抽象),即使我可以。例如。如果我要做一些非常不具备错误集合的东西。比如做随机访问 - 即使我可以编写我的代码来处理List,也会导致效率低下。