首页 文章

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

提问于
浏览
5

我正在尝试在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 回答

  • 5

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

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

    你要做的是:

    • 使 CustomCollection[A] 继承 TraversableLike

    • CustomCollection[A] 继承 GenericTraversableTemplate

    • 创建 CustomCollection 的伴随对象并添加一个隐含的返回 GenericCanBuildFrom

    • CustomCollection 随播广告中的构建器提供默认实现

    CustomCollection 的实现者需要提供具有构建器实现和隐式 CanBuildFrom 对象(可以简单地为 GenericCanBuildFrom )的伴随对象 .

    编辑:

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

相关问题