简体   繁体   English

无法调用接受并返回特征中自引用参数化类型的对象的函数

[英]Cannot call a function that accepts and returns an object of a self-referential parametrised type in a trait

Does anybody have an explanation for why the following invocation of foo() is illegal and returns the error: 有没有人解释为什么以下调用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) 
  }

}

From a human point of view it should be OK, since we have a function that accepts a type T and returns a type T. Then we have two objects t1 of type T and t2 of type T. One of the objects has method .foo() and the other is of the required type, so the call should be successful. 从人的角度来看应该没问题,因为我们有一个接受类型T并返回类型T的函数。然后我们有两个类型为t的对象t1和类型为T的t2。其中一个对象有方法.foo ()和另一个是所需类型,因此调用应该是成功的。 What is wrong with this line of reasoning? 这种推理有什么问题?

Good question. 好问题。 When you write T <: Foo[_] it translates to the existential type T <: Foo[X] forSome {type X} . 当你写T <: Foo[_]它转换为存在类型T <: Foo[X] forSome {type X} The Scala compiler refers to the instance of X as _$1 to avoid collision with existing symbol names. Scala编译器将X的实例称为_$1以避免与现有符号名称冲突。 In your example, both t1 and t2 have type T . 在您的示例中, t1t2都具有类型T When you call t1.foo you're treating t1 as a Foo[_$1] , so the expected parameter should have type _$1 . 当你调用t1.foo你将t1视为Foo[_$1] ,所以期望的参数应该是_$1类型。 Instead, the compiler finds t2 with type T , which doesn't match. 相反,编译器找到类型为T t2 ,它不匹配。 To fix the problem, you must place a more constrained type bound on T: 要解决此问题,您必须在T上放置一个更受约束的类型绑定:

trait Foo[T <: Foo[T]] {
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM