假设我想扩展SeqLike
的功能:
import collection.SeqLike
implicit class Test[A, Repr <: SeqLike[A, Repr]](val sq: Repr) extends AnyVal {
def foo(): Repr = sq
}
然后这不起作用:
Vector(1, 2, 3).foo()
也不是:
new Test(Vector(1, 2, 3)).foo()
<console>:41: error: inferred type arguments
[Nothing,scala.collection.immutable.Vector[Int]]
do not conform to class Test's type parameter bounds
[A,Repr <: scala.collection.SeqLike[A,Repr]]
new Test(Vector(1, 2, 3)).foo()
^
只有这样才有效:
new Test[Int, Vector[Int]](Vector(1, 2, 3)).foo()
如何让隐式类工作?
答案 0 :(得分:2)
只需输入sq
作为SeqLike
而不是类型参数。这将允许编译器有一些可依赖的坚实基础,然后可以推断Repr
。
现在唯一明显的问题是我们在foo
中会出现类型不匹配,因为它应该返回Repr
但我们会返回SeqLike[A, Repr]
。
解决方案很简单,使用repr
方法:
implicit class Test[A, Repr](val sq: SeqLike[A, Repr]) extends AnyVal {
def foo(): Repr = sq.repr
}
Vector(1, 2, 3).foo()
答案 1 :(得分:1)
我通常会这样解决这个问题:
implicit class Test[A, Repr <: SeqLike[A, Repr]](val sq: Repr with SeqLike[A, Repr]) extends AnyVal {
但是,这对Array
或String
无效,因此IsTraversableLike
是更好的解决方案。如果您确实需要SeqLike
,则很容易复制IsTraversableLike
。