我正试图通过Traversable
拉皮条为implicit class
特征添加一些方法。
但我有点CanBuildFrom
特质迷失了。请考虑以下事项:
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 =&gt; println(name +“:”+ a); a}(bf) ^
我猜是因为Repr
中的CanBuildFrom[-Repr, -Elem, +To]
是逆变的,因此Repr
上限Traversable[A]
可能不起作用。
但总的来说,我很失落。有人可以帮忙吗?
答案 0 :(得分:6)
您必须使用TraversableLike
及更高级别的kinded类型才能使类型推断器满意并使其与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
类