Scala嵌套自我类型



为什么不行:

scala> trait A
defined trait A
scala> class Z {
     | this: A =>
     | }
defined class Z
scala> class Y {
     | this: A =>
     | val z = new Z()
     | }
<console>:11: error: class Z cannot be instantiated because it does not conform to its self-type Z with A
       val z = new Z()

我想让混合到Y中的A再次混合到Y中的Z实例中,我怎么做呢?

在上面的例子中,

EDIT(试图写得太简短。这是我的实际问题):

scala> import scala.slick.driver.ExtendedProfile
import scala.slick.driver.ExtendedProfile
scala> class Z {
     | this: ExtendedProfile =>
     | }
defined class Z
scala> class Y {
     | this: ExtendedProfile =>
     | val z = new Z() with ExtendedProfile
     | }
<console>:21: error: illegal inheritance;
 self-type Z with scala.slick.driver.ExtendedProfile does not conform to scala.slick.driver.ExtendedProfile's selftype scala.slick.driver.ExtendedDriver
       val z = new Z() with ExtendedProfile
                        ^

我想我明白为什么不编译,但这不应该是隐式的(不是实际的scala关键字'隐式',只是一般隐式;))?如果ExtendedProfile总是必须有一个ExtendedDriver,为什么new Z()抱怨它需要一个ExtendedDriver?

供参考:http://slick.typesafe.com/doc/1.0.0-RC1/api/scala.slick.driver.ExtendedProfile

编译错误说您需要提供一个A mix-in来实例化一个Z对象。正如om-non-nom所建议的,您的代码编译时只需要做一个小的更改,

trait A
class Z { this: A =>
}
class Y { this: A =>
  val z = new Z with A
}

这里有一个使用继承而不是self类型的替代方案,可能更接近您的意图:

trait Y extends A {
  val z = new Z with Y
}

编辑

回答你更新的问题,自我类型是类型构造上的约束。自类型与继承的不同之处在于它们不扩展类型的外部接口。

从你链接的Scaladoc中,看起来是这样的情况:

trait ExtendedDriver extends ExtendedProfile
trait ExtendedProfile { self: ExtendedDriver => }
class Z { this: ExtendedProfile => }
class Y {
  this: ExtendedProfile =>
  val z = new Z() with ExtendedProfile
}

问题是ExtendedProfile不继承ExtendedDriver,不能单独存在;它需要提供显式的ExtendedDriver。你可以用

new Z() with ExtendedProfile with ExtendedDriver

这实际上是多余的,因为ExtendedProfile已经混合在一起了。你只需要,

new Z() with ExtendedDriver

最新更新