关于这个主题有无数的问题,这里有一篇非常好的,如果不是非常精确的措辞:Revisiting implicits without the import tax。我已经阅读了大部分内容,但在覆盖默认CanBuildFrom
含义时遇到问题,而不自行重复声明。如果您熟悉scala集合库和CanBuildFrom
的解析,则您知道对于每个scala集合特征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
的要求水平越来越高。
答案 0 :(得分: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集合中的所有含义。
足够好,但我想知道是否可以直接这样做。