我在使用Scala时遇到了一些麻烦,并明确键入了自引用特征。我有两个特点和一个实现:
trait A {
def print(msg: String): Unit
}
class AImpl extends A {
def print(msg: String): Unit = println(msg + " from A")
}
trait B { self: A =>
override def print(msg: String): Unit = self.print(msg + " from B")
}
val a = new AImpl with B
a.print("Hello, World!")
我希望a.print("Hello, World!")
打印Hello, World! from B from A
。它编译时没有任何错误,但在运行时抛出了StackOverflowError。
这是我制作的Scastie。
答案 0 :(得分:2)
你所做的实际上是这样的:
trait B {
def print(msg: String): Unit = this.print(msg + " from B") //Recursively build up stack until overflow
}
请注意,self
只是this
的别名,而不是super
的别名。此外,由于A
是自我类型,因此它不是B
的超级类型,因此您无法调用super.print
。因此,您已成功覆盖了print
中的AImpl
,但您没有调用您创建的print
impl。
<强>更新强>
要实现您想要的目标,您需要扩展A
而不是将其用作自我类型(对不起,但您无法通过自我类型执行您想要的操作):
trait B extends A {
abstract override def print(msg: String): Unit = super.print(msg + " from B")
}