【问题标题】:How to define implicit class for Traversable with CanBuildFrom?如何使用 CanBuildFrom 为 Traversable 定义隐式类?
【发布时间】:2016-04-09 10:10:58
【问题描述】:

我正在尝试通过implicit class 拉皮条向Traversable trait 添加一些方法。

但我有点迷失CanBuildFrom trait。考虑以下几点:

implicit class TraversableExt[+A, +Repr <: Traversable[A]](traversable: Repr) {
  def debug[That](name: String)(implicit bf: CanBuildFrom[Repr, A, That]): That =
    traversable.map{ a => println(name + ": " + a); a }(bf)
}

这失败并出现错误:

错误:(21, 59) 类型不匹配;
找到:scala.collection.generic.CanBuildFrom[Repr,A,That]
必需:scala.collection.generic.CanBuildFrom[Traversable[A],A,That]
traversable.map{ a => println(name + ": " + a);一个}(bf) ^

我猜因为CanBuildFrom[-Repr, -Elem, +To] 中的Repr 是逆变的,因此我的ReprTraversable[A] 的上限可能不起作用。

但总的来说,我很迷茫。有人可以帮忙吗?

【问题讨论】:

    标签: scala scala-collections


    【解决方案1】:

    您必须使用TraversableLike 和更高种类的类型才能使类型推断器满意并使其与CanBuildFrom 一起工作:

    implicit class TraversableExt[A, C[X] <: TraversableLike[X, C[X]]](traversable: C[A]) {
      def debug[That](name: String)(implicit bf: CanBuildFrom[C[A], A, That]): That =
        traversable.map{ a => println(name + ": " + a); a }(bf)
    }
    

    编译器现在能够正确推断集合的类型C[A],而不是一般地寻找CanBuildFrom[Traversable[A],...]

    根据经验,当您想要返回与传入的集合类相同的集合类时,您必须使用*Like

    【讨论】:

      猜你喜欢
      • 2016-06-18
      • 2017-05-16
      • 2020-05-26
      • 1970-01-01
      • 2020-03-29
      • 1970-01-01
      • 1970-01-01
      • 2019-10-20
      • 2016-05-15
      相关资源
      最近更新 更多