我正在尝试在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 }
这不会编译,因为CustomCollection.map()返回Traversable . 我想我需要定义一个CanBuildFrom,但是我需要定义一个从头构建实例的apply()方法 . 我不想指定一种方法来构建它;这应该取决于实施者 . 这可能吗?
1 回答
如果希望
map
返回更具体的集合类型,则还应继承TraversableLike
,并将第二个类型参数(表示类型)设置为CustomCollection[A]
.接下来,
map
需要一个类型为CanBuildFrom
的隐式参数 . 它将在CustomCollection
的伴随对象中查找该类型的符合隐含值 . 如果您查看Seq
类的源代码,您将看到它们的随播提供了类型为GenericCanBuildFrom
的CanBuildFrom
对象,它们将构建器的调用转发回请求构建器的集合 . 这样,Seq
变换器方法的返回类型的动态类型(例如map
)始终与序列本身的类型相同 .你要做的是:
使
CustomCollection[A]
继承TraversableLike
让
CustomCollection[A]
继承GenericTraversableTemplate
创建
CustomCollection
的伴随对象并添加一个隐含的返回GenericCanBuildFrom
为
CustomCollection
随播广告中的构建器提供默认实现CustomCollection
的实现者需要提供具有构建器实现和隐式CanBuildFrom
对象(可以简单地为GenericCanBuildFrom
)的伴随对象 .编辑:
上面提到的
GenericTraversablTemplate
是必需的,因为它首先确保集合将具有GenericCanBuildFrom
构建器工厂调用的genericBuilder
方法 . 其次,它确保集合实际上具有GenericCompanion
类型的伴随对象 .