如何在不定义实现的情况下在Scala中定义自定义集合接口?

tra*_*ble 5 scala scala-2.8 scala-collections

我正在尝试在Scala 2.8中定义自定义集合接口.我想要求子类是Traversable,还有其他一些行为.我也想像map()这样的方法返回相应的类型,如下所示:

trait CustomCollection[+A] extends Traversable[A] {
    def customOperation(i:Int):Int // for example
}

def incrementAll(c:CustomCollection[Int]):CustomCollection[Int] = c.map { _ + 1 }
Run Code Online (Sandbox Code Playgroud)

这不会编译,因为CustomCollection.map()返回Traversable.我想我需要定义一个CanBuildFrom,但是我需要定义一个从头构建实例的apply()方法.我不想指定一种方法来构建它; 这应该取决于实施者.这可能吗?

axe*_*l22 5

如果要map返回更具体的集合类型,则还应继承TraversableLike,并将第二个类型参数(表示形式类型)设置为CustomCollection[A].

接下来,map需要一个类型的隐式参数CanBuildFrom.它将查找伴随对象,CustomCollection以找到该类型的符合隐含值.如果您查看Seq类的源代码,您将看到它们的随播提供CanBuildFrom了类型的对象,GenericCanBuildFrom这些对象将构建器的调用转发回请求构建器的集合.这样,Seq变换器方法的返回类型的动态类型(例如map)总是与序列本身的类型相同.

你要做的是:

  1. CustomCollection[A]继承TraversableLike
  2. CustomCollection[A]继承GenericTraversableTemplate
  3. 创建一个伴随对象CustomCollection并添加一个返回a的隐式对象GenericCanBuildFrom
  4. CustomCollection协同服务器中的构建器提供默认实现

的实施者CustomCollection将需要提供具有助洗剂的实施和隐性的同伴对象CanBuildFrom的对象(这可以简单地将GenericCanBuildFromS).

编辑:

GenericTraversablTemplate需要上面提到的,因为它首先确保集合将具有构建器工厂genericBuilder调用的方法GenericCanBuildFrom.其次,它确保集合实际上具有类型的伴随对象GenericCompanion.