如何解决是否可以像旧的 CanBuildFrom 那样隐式获取集合的构建器?
我有一些旧代码依赖于隐式 CanBuildFrom
来构建指定为类型参数的类型的集合。从 2.12 开始,在新的集合库中,替换 BuildFrom
不提供无参数 Builder
工厂方法。我想要的是集合的 IterableFactory
,但这些是伴随对象,不是隐式的。 是否可以在不引入我自己的隐式工厂类的情况下移植它,为库中的每个集合类包装一个 Factory
?我知道这些工厂有很多风格,但即使我有为那些接受隐性证据的人添加一个特殊情况,它仍然会比我的要好得多。
新代码中一个明智的选择可能是将 IterableFactory
作为(值)参数而不是依赖显式类型参数,但它需要在太多地方进行更改,所以我宁愿坚持到当前架构并制作样板。
解决方法
如果您想使用 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,10,1)
scala> fill[Array](10).toSeq
res2: Seq[String] = ArraySeq(1,10)
标准库中为 Factory
和 String
提供了单独的隐式 Array
。并且对于所有 Iterable
(List
、Map
、Set
等)它都有效,因为 Iterable
的伴随对象扩展了 {{ 3}} 类,提供 implicit def iterableFactory[A]: Factory[A,CC[A]]
方法。
您可以使用类型参数代替隐式。
def listToString[A,CC[x] <: Iterable[x]](
list: collection.IterableOps[A,CC,CC[A]]
): CC[String] =
list.map(x => x.toString)
listToString(List(1,4))
-> List(1,4): List[String]
listToString(Set("foo","bar","baz"))
-> Set(foo,bar,baz): scala.collection.immutable.Set[String]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。