什么时候选择键入给定函数的返回类型为Seq、Iterable和Traversable (或者在Seq的层次结构中更深层)?
你是如何做出这个决定的?我们有很多默认情况下返回Seq的代码(通常从DB查询和后续转换的结果开始)。我倾向于在默认情况下将返回类型设置为Traversable,在指定的情况下将返回类型设置为Seq。但我没有充分的理由这样做。
我非常熟悉每个特征的定义,所以请不要用定义这些术语来回答。
发布于 2012-07-29 01:09:58
这是一个好问题。你必须平衡两个关注点:
通用,这样你以后可以改变实现
上执行
其中(1)要求您尽可能详细地说明类型(例如Seq上的Iterable ),而(2)则要求您提供相反的信息。
即使返回类型只是Iterable,您仍然可以返回一个Vector,所以如果调用者希望获得额外的能力,它可以只对其调用.toSeq或.toIndexedSeq,并且该操作对于Vector来说是很便宜的。
作为衡量平衡的一种措施,我想补充第三点:
Seq。如果您可以假设不会出现两个相等的对象,则给出一个Set。等。以下是我的经验法则:
Set,Map,Seq,IndexedSeqList而不是Seq。它允许调用者只使用cons extractorscollection.immutable.IndexedSeq)Vector),而是通用类型(IndexedSeq),它提供相同的Iterator实例,则调用者可以很容易地生成一个严格的结构,例如,通过调用toList on It 当然,这是我个人的选择,但我希望它听起来是合理的。
发布于 2015-05-02 05:38:16
当您需要按索引访问时,默认情况下
Seq everywhere.IndexedSeq。中使用其他任何内容
这些是“常识性”的指导方针。它们简单、实用,在平衡原则和性能的同时,在实践中也能很好地工作。这些原则是:
接口使用反映数据组织方式的类型(感谢方法参数和返回类型中的OP和ziggystar).
Seq同时满足这两个原则。如http://docs.scala-lang.org/overviews/collections/seqs.html中所述
序列是一种具有有限长度且元素具有固定索引位置(从0开始)的可迭代序列。
90%的情况下,你的数据是一个序列。
其他注释:
List是一种实现类型,所以您不应该在API中使用它。例如,如果不通过conversion.Iterable,Vector就不能用作List,因为它没有定义length。Iterable跨有限的序列和潜在的无限流进行抽象。大多数时候,我们要处理的是有限序列,所以你“有一个长度”,而Seq反映了这一点。通常情况下,您实际上不会使用长度。但是它是经常需要的,而且很容易提供,所以使用Seq.缺点:
这些“常识”约定有一些轻微的缺点。
case head :: tail => ...。您可以使用here中描述的:+和+:。但是,重要的是,在Scala: Pattern matching Seq[Nothing].中描述的Nil上的匹配仍然有效
脚注:
Map,因为问题并没有问到它。是一致的
发布于 2012-07-29 00:50:06
使你的方法的返回类型尽可能的具体。然后,如果调用者希望将其保留为SuperSpecializedHashMap或键入为GenTraversableOnce,他们可以这样做。这就是编译器在默认情况下推断最具体类型的原因。
https://stackoverflow.com/questions/11702798
复制相似问题