0

这个问题遵循Cake 模式中的一个问题,其中覆盖抽象类型不与 Upper Type Bounds 一起工作。我想用<:. 前面的链接给出了解决方案,其中包括通过写入特征 S 来改变线性化的顺序。但是,我添加了一个在以下代码中this: Cake with S命名的控制抽象。control我想调用其中的方法t

trait A {
  def ping = println("ping")
}

trait Cake {
  type T
}

trait S { this: Cake with S =>
  type T <: A with S
  def t: T
  def s = println("test")
  // def control(c: =>T): T = c // compile
  // def control(c: =>T): T = c.s // does not compile
  def control(c: =>T): T = c.t // does not compile
  t.ping
  t.s
}

但是,这段代码会导致我无法解释的编译错误

 found   : S.this.T#T
 required: S.this.T
         def control(c: =>T): T = c.t
                                    ^

怎么了 ?

4

1 回答 1

1
def control(c: =>T): T

有返回类型S#T。显然,c也有类型T。因此,返回c

def control(c: =>T): T = c

编译,而返回c.s不编译,因为s返回类型为Unit. c.t无法编译,因为它的返回类型为S#T#T.

因此,将编译以下内容:

def control(c: =>T): T#T = c.t

由于这里发生的所有事情背后的细节一般来说有点不重要,我建议你谷歌“类型投影”和“路径依赖类型”以获取更多信息。

本质上发生的事情是c有类型T,在哪里T <: A with S,所以我们知道T必须有所有S的成员,其中一个被定义为def t: T。但这T不一定与我们的 相同,因此当我们在您的示例中T调用时它不符合要求。c.t我们想要的是Tof 类型T(或等价T的 'sTT我们的 type member T)。这里T#T准确地表明了我们想要的。

于 2013-01-10T17:44:10.060 回答