微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

是否可以像旧的 CanBuildFrom 那样隐式获取集合的构建器?

如何解决是否可以像旧的 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)

标准库中为 FactoryString 提供了单独的隐式 Array。并且对于所有 IterableListMapSet 等)它都有效,因为 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)

Using it

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 举报,一经查实,本站将立刻删除。