0

为什么这不起作用:

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 的实例中。我该怎么做?

编辑(在上面的例子中试图过于简短。这是我的实际问题):

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

4

1 回答 1

1

编译错误表明您需要提供一个A混合来实例化一个Z对象。正如 om-non-nom 建议的那样,您的代码只需稍作改动即可编译,

trait A

class Z { this: A =>
}

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

这是使用继承而不是自我类型的替代方案,并且可能更接近您的意图:

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
于 2013-01-11T17:20:03.890 回答