首页 > 解决方案 > 是否可以像旧的 CanBuildFrom 那样隐式获取集合的构建器?

问题描述

我有一些旧代码依赖于隐式CanBuildFrom来构建指定为类型参数的类型的集合。从 2.12 开始,在新的集合库中,替换BuildFrom不提供无参数Builder工厂方法。我想要的是IterableFactory集合,但这些是伴随对象,它们不是隐式的。我可以以某种方式移植它而不引入我自己的隐式工厂类Factory,为库中的每个集合类包装一个吗?我知道那些工厂有很多口味,但即使我必须为那些接受隐含证据的人添加一个特例,它仍然比我拥有的要好得多。

新代码中一个明智的选择可能是将IterableFactory作为(值)参数而不是依赖于显式类型参数,但这需要在太多地方进行更改,所以我宁愿坚持当前架构并做样板.

标签: scalascala-collectionsimplicit

解决方案


如果您想使用 a 和没有先前现有的集合逐个元素地构建通用集合Builder,则可以使用隐式Factory参数。例如:

import scala.collection.Factory

class Filler[T](makeElement: Int => T) {
  def apply[C[_]](n: Int)(implicit factory: Factory[T, C[T]]): C[T] = {
    val builder = factory.newBuilder
    for (i <- 1 to n) builder += makeElement(i)
    builder.result()
  }
}

你可以像这样使用它:

scala> val fill = new Filler(_.toString)
fill: Filler[String] = Filler@154f8280

scala> fill[Vector](10)
res0: Vector[String] = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> fill[Set](10)
res1: Set[String] = HashSet(8, 4, 9, 5, 10, 2, 7, 3, 6, 1)

scala> fill[Array](10).toSeq
res2: Seq[String] = ArraySeq(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

Factory标准库中为Strings 和Arrays 提供了单独的隐式s。并且对于所有Iterables ( List, Map, Set, 等) 它都有效,因为Iterables 的伴随对象扩展了IterableFactory提供implicit def iterableFactory[A]: Factory[A, CC[A]]方法的类。


推荐阅读