我如何一般地处理Scala集合?

lee*_*777 4 collections scala

我已经意识到我传递Scala集合的典型方式可以使用一些改进.

def doSomethingCool(theFoos: List[Foo]) = { /* insert cool stuff here */ }

// if I happen to have a List
doSomethingCool(theFoos)

// but elsewhere I may have a Vector, Set, Option, ...
doSomethingCool(theFoos.toList)
Run Code Online (Sandbox Code Playgroud)

我倾向于编写我的库函数来List作为参数类型,但我确信有一些更通用的东西我可以放在那里以避免.toList我在应用程序代码中偶尔的调用.这特别令人讨厌,因为我的doSomethingCool函数通常只需要调用map,flatMap并且filter在所有集合类型上定义.

对于那种"更普遍的东西",我有哪些选择?

Dan*_*ral 6

以下是更一般的特征,每个特征都扩展了前一个特征:

  • GenTraversableOnce
  • GenTraversable
  • GenIterable
  • GenSeq

上述特征未指定集合是顺序还是并行.如果您的代码要求按顺序执行某些操作(通常,如果您的代码具有任何类型的副作用),则它们过于笼统.

以下特征要求顺序执行:

  • TraversableOnce
  • Traversable
  • Iterable
  • Seq
  • LinearSeq

第一个,TraversableOnce只允许您在集合上调用一个方法.之后,该集合已被"使用".作为交换,它通常足以接受迭代器和集合.

Traversable是一个非常通用的集合,拥有大多数方法.但是,有些事情是不能做的,在这种情况下你需要去Iterable.

全部Iterable实现该iterator方法,允许您获取Iterator该集合.这使它具有一些不存在的方法的能力Traversable.

A Seq[A]实现了该函数Int => A,这意味着您可以通过索引访问任何元素.这不能保证有效,但它保证每个元素都有一个索引,并且您可以对该索引的内容进行断言.与此对比MapSet,在那里你不能告诉一个元素的索引是什么.

一个LinearSeq是一个Seq,能快速head,tail,isEmpty和前置.这是尽可能接近a List而不实际使用List显式.

或者,您可以拥有一个IndexedSeq具有快速索引访问权限(某些内容List未提供).

另请参阅此问题以及基于此的常见问题解答.