2

关于这个话题有无数的问题,如果不是非常准确的话,这里有一篇相当不错的文章:Revisiting implicits without the import tax。我已经阅读了其中的大部分内容,但是在CanBuildFrom不自己重复声明的情况下覆盖默认隐式存在问题。如果您熟悉 scala 集合库和 的解析CanBuildFrom,您就会知道对于每个 scala 集合 trait CC[X],它的伴生对象都定义了一个隐式CanBuildFrom[CC[_], X, CC[X]]实例。我已经介绍了我自己的集合层次结构,它植根于一个派生自的类IndexedSeq[X]

trait SpecSeq[X] extends IndexedSeq[X]
trait MutableSeq[X] extends SpecSeq[X]
trait ConstSeq[X] extends SpecSeq[X]
trait ArraySeq[X] extends MutableSeq[X]
trait ConstArray[X] extends ConstSeq[X]

我可以避免在所有已定义特征的伴随对象中声明隐式值,而是将它们提取到伴随对象的公共基本特征中吗?我尝试过:

trait SpecCompanion[S[X]<:SpecSeq[X]] {
    implicit def canBuildFrom[X] :CanBuildFrom[S[_], X, S[X]] = ???
}
ArraySeq extends SpecCompanion[ArraySeq]
ConstArray extends SpecCompanion[ConstArray]
...

不幸的是,这些定义并没有被认为比object IndexedSeq. 由于实际上它不是一个单一的隐含值,而是随着对X.

4

1 回答 1

0

我最终得到了一层间接和我自己的子类CanBuildFrom

trait SpecCanBuildFrom[-F, -E, +T] extends CanBuildFrom[F, E, T]

trait SpecCompanion[S[X]<:SpecSeqw[X]] {
    implicit def cbf[X] :SpecCanBuildFrom[S[_], X, S[S]] = ???
}

object SpecSeq extends SpecCompanion[SpecSeq] {
    implicit def canBuildFrom[C[X]<:SpecSeq[X], X](implicit ev :SpecCanBuildFrom[C[_], X, C[X]) :CanBuildFrom[C[_], X, C[X]] = ev
}

object ArraySeq extends SpecCompanion[ArraySeq]
object ConstArray extends SpecCompanion[ConstArray]

现在 SpecSeq 中的泛型定义覆盖了 scala 集合中的所有隐式。

足够好,但我想知道是否可以直接进行。

于 2016-06-20T10:54:39.313 回答