事情在范围内。
更简单的例子是
trait A { type T }
implicit val a: A { type T = Int } = null
def test(implicit x: A): Unit = {
implicitly[x.T =:= Int] // doesn't compile, cannot prove that x.T =:= Int
}
你假设x
is a
(aIsBaseTc
is doubleHoldsTypeMember
在你的注释中)。但实际上x
is not a
, x
将在何时解决test
被称为(在范围内test
调用站点)但是a
是在当前范围内定义的(范围test
定义)。相似地,aIsBaseTc
is not doubleHoldsTypeMember
.
当使用类型参数进行隐式解析时,为什么 val 放置很重要?(参见之间的区别implicit x: X
and implicitly[X]
.)
对于任何匿名类
implicit val containerOfDoubleIsActual = new IsActualTC[Container[Double], Double] {
def get(self: Self) = self.get // type mismatch;
}
是一个简写
class IsActualTCImpl extends IsActualTC[Container[Double], Double] {
def get(self: Self) = self.get // type mismatch;
// aIsBaseTc is not doubleHoldsTypeMember here
}
implicit val containerOfDoubleIsActual =
new IsActualTCImpl // implicit is resolved here
// aIsBaseTc becomes doubleHoldsTypeMember here
自从aIsBaseTc
is not doubleHoldsTypeMember
, aIsBaseTc.Self
is not Double
.
可能的修复方法是再添加一个类型参数S
to IsActualTC
abstract class IsActualTC[A, T, S](implicit val aIsBaseTc: IsBaseTC[T] {type Self = S}) extends IsBaseTC {
type Self = A
def get(self: A): S
}
implicit val containerOfDoubleIsActual = new IsActualTC[Container[Double], Double, Double] {
def get(self: Self) = self.get
}
或向隐式参数添加类型细化IsActualTC
abstract class IsActualTC[A, T](implicit val aIsBaseTc: IsBaseTC[T] {type Self = T}) extends IsBaseTC {
type Self = A
def get(self: A): aIsBaseTc.Self
}
implicit val containerOfDoubleIsActual = new IsActualTC[Container[Double], Double] {
def get(self: Self) = self.get
}