繁体   English   中英

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

[英]How do I deal with Scala collections generically?

我已经意识到我传递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)

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

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

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

  • GenTraversableOnce
  • GenTraversable
  • GenIterable
  • GenSeq

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

以下特征要求顺序执行:

  • TraversableOnce
  • Traversable
  • Iterable
  • Seq
  • LinearSeq

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

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

所有Iterable实现了iterator方法,它允许您获取该集合的Iterator 这使它能够使用Traversable不存在的一些方法。

Seq[A]实现函数Int => A ,这意味着您可以通过索引访问任何元素。 这不能保证有效,但它保证每个元素都有一个索引,并且您可以对该索引的内容进行断言。 将其与MapSet对比,您无法分辨元素的索引。

LinearSeq是一个提供快速headtailisEmpty和prepend的Seq 这是尽可能接近List而不实际明确使用List

或者,您可以拥有一个IndexedSeq ,它具有快速索引访问权限( List不提供)。

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

其中最明显的是使用Traversable作为,这将有你想要的东西最一般的特质。 但是,我认为你通常更好地坚持:

  • Seq
  • IndexedSeq
  • Set
  • Map

Seq将覆盖ListVector等, IndexedSeq将覆盖Vector等等。我发现自己不使用Iterable因为我经常需要(或想要)知道我拥有的东西的大小并且返回预scala-2.8 Iterable没有提供访问权限对此 ,所以我总是不得不把事情变成序列!

看起来像TraversableIterable现在有size方法,所以也许我应该回去使用它们! 当然,您可以使用GenTraversableOnce开始“疯狂”,但这不太可能有助于提高可读性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM