46 scala
您何时选择将给定函数的返回类型键入Seqvs Iterablevs Traversable(或者甚至更深入Seq的层次结构中)?
你是如何做出这个决定的?我们有很多代码Seq默认返回s(通常从数据库查询和连续转换的结果开始).我倾向于在Traversable默认情况下以及Seq在特定期望给定订单时创建返回类型.但我没有充分的理由这样做.
我完全熟悉每个特性的定义,所以请不要回答定义术语.
0__*_*0__ 35
这是一个很好的问题.你必须平衡两个问题:
其中(1)要求你对类型(例如Iterable结束Seq)的具体细节,并且(2)问你相反.
即使返回类型只是Iterable,你仍然可以返回让我们说a Vector,所以如果调用者希望获得额外的功率,它可以只是调用.toSeq或.toIndexedSeq在它上面,并且该操作对于a来说是便宜的Vector.
作为平衡的衡量标准,我想补充第三点:
Seq.如果你可以假设不会出现两个相同的对象,那就给出一个Set.等等.以下是我的经验法则:
Set,Map,Seq,IndexedSeqList赞成使用Seq.它允许调用者与cons提取器进行模式匹配collection.immutable.Set,collection.immutable.IndexedSeq)Vector),而是IndexedSeq使用相同API 的通用类型()Iterator实例,那么调用者可以很容易地生成一个严格的结构,例如通过调用toList它IndexedSeq当然,这是我个人的选择,但我希望听起来很清醒.
Seq在任何地方默认使用。IndexedSeq当您需要通过索引访问时使用。这些是“常识”指南。它们简单、实用,并且在平衡原则和性能的同时在实践中运行良好。原则是:
Seq满足这两个原则。如http://docs.scala-lang.org/overviews/collections/seqs.html 中所述:
序列是一种具有 [有限] 长度的可迭代对象,其元素具有固定的索引位置,从 0 开始。
90% 的情况下,您的数据是 Seq。
其他注意事项:
List是一种实现类型,因此您不应在 API 中使用它。AVector例如不能用作List无需通过转换去。Iterable没有定义length。 Iterable跨有限序列和潜在的无限流进行抽象。大多数情况下,人们正在处理有限序列,因此您“有一个长度”,并Seq反映了这一点。通常,您实际上不会使用长度。但是它经常被需要,并且很容易提供,所以使用Seq.缺点:
这些“常识”约定有一些轻微的缺点。
case head :: tail => .... 您可以按照此处的说明使用:+和。然而,重要的是,匹配仍然按照Scala:模式匹配 Seq[Nothing] 中的描述工作。+:Nil脚注:
Map在这里讨论,因为这个问题,明智地,并没有问到它。使方法的返回类型尽可能具体。然后,如果调用者想要将其保留为 aSuperSpecializedHashMap或将其键入为 a GenTraversableOnce,他们可以。这就是编译器默认推断最具体类型的原因。
| 归档时间: |
|
| 查看次数: |
8105 次 |
| 最近记录: |