Scala递归泛型:父[Child]和Child [Parent]

Mar*_*ing 4 generics types scala

更新:澄清和扩展,因为原始问题被简化得太过分了

我需要一对特征,每个特征引用另一个特征,使父类和子类必须相互关联.

trait Parent [C <: Child] {
  def foo(c: C)
}

trait Child [P <: Parent] {
  def parent: P = ...
  def bar = parent.foo(this)
}
Run Code Online (Sandbox Code Playgroud)

这样实现类必须成对出现:

class ActualParent extends Parent [ActualChild] {
  def foo(c: ActualChild) = ...
}

class ActualChild extends Child [ActualParent] {
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,编译器不喜欢这些特性,因为泛型类型并不完整.而不是C <: Child需要说C <: Child[些什么].如果不指定它们也不起作用:

trait Parent [C <: Child[_]] {
  def foo(c: C)
}

trait Child [P <: Parent[_]] {
  def parent: P = ...
  def bar = parent.foo(this)
}
Run Code Online (Sandbox Code Playgroud)

它现在在线上抱怨parent.foo(this),因为它不知道它this是正确的类型.该类型的parent需求,是Parent[this.type]为调用foo有正确的类型.

我认为必须有一种方式来引用一个对象自己的类型?或者是一个需要自己的类型?


更新:继@ Daniel的答案之后,我尝试在子节点中使用抽象类型成员来声明父类型的泛型类型,如下所示:

trait Parent [C <: Child] {
  def foo(c: C)
}

trait Child {
  type P <: Parent[this.type]

  def parent: P = ...
  def bar = parent.foo(this)
}
Run Code Online (Sandbox Code Playgroud)

当我尝试实现它时,这不起作用:

class ActualParent extends Parent [ActualChild] {
  def foo(c: ActualChild) = ...
}

class ActualChild extends Child {
  type P = ActualParent
}
Run Code Online (Sandbox Code Playgroud)

给出以下错误:

overriding type Parent in trait Child with bounds >: Nothing <: Parent[ActualChild.this.type]
type Parent has incompatible type
Run Code Online (Sandbox Code Playgroud)

那是什么意思?

Ale*_*nov 5

您可以使用http://programming-scala.labs.oreilly.com/ch13.html中给出的方法:

abstract class ParentChildPair {
  type C <: Child
  type P <: Parent

  trait Child {self: C =>
    def parent: P
  }

  trait Parent {self: P =>
    def child: C
  }
}

class ActualParentChildPair1 {
  type C = Child1
  type P = Parent1

  class Child1 extends Child {...}

  class Parent1 extends Parent {...}
}
Run Code Online (Sandbox Code Playgroud)