自引用泛型

时间:2013-02-18 15:38:10

标签: scala

我搜索了一下但是我无法找到这样一个结构的例子:

Person[P <: Person[P]]

以我理解的方式解释。

这是如何解决的?它看起来像是对我的无休止的递归,但似乎我错误地得出了这个结论。

2 个答案:

答案 0 :(得分:5)

结构本身在Twitter Scala School中解释,称为F-有界多态。

// you define it like this
trait X extends Person[X]

// it then gets expanded to this
trait Person[X extends Person[X]]

当特征需要引用它所扩展的对象的类型时,使用此结构。如果Scala学校的解释不够,您可以在互联网上搜索“F-bounded polymorphism”

答案 1 :(得分:5)

这有时被称为自我类型(不要与Scala的显式类型自引用相混淆)并且它通常用于具有足够强大的方法签名来表示该方法使用与接收器相同类型的对象。

让我们看一个例子。比方说,您有一个基本特征Animal,其中包含通用breed方法,需要另一个Animal并返回Animal

trait Animal {
  def breed(a: Animal): Animal
}

好的,但你真正想要的是一种breed方法,它表示每只具体的动物只与同一类动物一起繁殖,并且还会返回同一类动物。以下实现

class Cow extends Animal {
  def breed(c: Cow) = new Cow
}

是不可能的,因为此breed的签名不匹配。覆盖也是不可能的,因为您需要协变地更改参数类型,这是禁止的。

救援的自我类型:

trait Animal[A <: Animal[A]] {
  def breed(a: A): A
}

class Cow extends Animal[Cow] {
  def breed(c: Cow) = new Cow
}

正如EECOLOR已经指出的那样,它背后的类型理论被称为 F-bounded polymorphism