不能调用在trait中接受并返回自引用参数化类型对象的函数



有人能解释一下为什么下面的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,以避免与现有的符号名冲突。在您的示例中,t1t2的类型都是T。当您调用t1.foo时,您将t1视为Foo[_$1],因此期望的参数类型应该是_$1。相反,编译器发现t2具有不匹配的T类型。要解决这个问题,必须在T:

上设置一个约束更严格的类型绑定。
trait Foo[T <: Foo[T]] {
...

最新更新