有人能解释一下为什么下面的foo()调用是非法的并且返回错误吗?
trait Foo[T<:Foo[_]] {
def foo(t: T): T
def test_foo(t1: T, t2: T): T = {
// produces error:
// type mismatch;
// found: t2.type (with underlying type T)
// required: _$1 where type _$1"
t1.foo(t2)
}
}
从人的角度来看,这应该是可以的,因为我们有一个接受类型T并返回类型T的函数。然后我们有两个类型T的对象t1和类型T的t2,其中一个对象具有.foo()方法,另一个是所需的类型,因此调用应该是成功的。这种推理方式有什么问题?
问得好。当你写T <: Foo[_]
时,它会转化为存在型T <: Foo[X] forSome {type X}
。Scala编译器将X
的实例称为_$1
,以避免与现有的符号名冲突。在您的示例中,t1
和t2
的类型都是T
。当您调用t1.foo
时,您将t1
视为Foo[_$1]
,因此期望的参数类型应该是_$1
。相反,编译器发现t2
具有不匹配的T
类型。要解决这个问题,必须在T:
trait Foo[T <: Foo[T]] {
...