generics - Scala 递归泛型 : Parent[Child] and Child[Parent]

标签 generics scala types

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

我需要一对特征,每个特征都指向另一个特征,这样父类和子类必须相互关联。

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

trait Child [P <: Parent] {
  def parent: P = ...
  def bar = parent.foo(this)
}

这样实现类必须成对出现:
class ActualParent extends Parent [ActualChild] {
  def foo(c: ActualChild) = ...
}

class ActualChild extends Child [ActualParent] {
}

不幸的是,编译器不喜欢这些特征,因为泛型类型不完整。而不是 C <: Child 它需要说 C <: Child[ 一些 ] 。不指定它们也不起作用:
trait Parent [C <: Child[_]] {
  def foo(c: C)
}

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

它现在在 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)
}

当我尝试实现它时,这不起作用:
class ActualParent extends Parent [ActualChild] {
  def foo(c: ActualChild) = ...
}

class ActualChild extends Child {
  type P = ActualParent
}

给出以下错误:
overriding type Parent in trait Child with bounds >: Nothing <: Parent[ActualChild.this.type]
type Parent has incompatible type

这意味着什么?

最佳答案

您可以使用 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 {...}
}

关于generics - Scala 递归泛型 : Parent[Child] and Child[Parent],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3886457/

相关文章:

types - 如何在 Kotlin 中正确处理大于 127 的字节值?

c# - C# 中的递归泛型类型参数

java - 泛型上的通配符错误

c++ - 错误 : expected type-specifier before Class

java - 实现通用工厂

scala - akka grpc自定义认证

scala - Spark负载模型并继续训练

scala - 如何生成集合的成对组合,而忽略顺序?

java - 从指定返回 Collection<ParentType> 的方法返回 Collection<ChildType>

java - 确认方法签名未被更改的测试?