带有惰性 val 的 Scala 线性化,为什么无限递归?

Art*_*ler 4 scala

尝试实现一个利用 Scala 线性化优势的结构时,我们发现了一些我们不理解的行为。

虽然如果将覆盖的字段设置为def,一切都会按预期进行,但如果我们将其设置为,它会因无限递归循环而崩溃lazy val

带有 defs 的代码:

trait T {
  def fields: List[Int] = Nil
}

trait A extends T {
  override def fields = 1 :: super.fields
}

trait B extends T {
  override def fields = 2 :: super.fields
}

val x = new B with A

println(x.fields)
Run Code Online (Sandbox Code Playgroud)

带有惰性值的代码:

trait T {
  def fields: List[Int] = Nil
}

trait A extends T {
  override lazy val fields = 1 :: super.fields
}

trait B extends T {
  override lazy val fields = 2 :: super.fields
}

val x = new B with A

println(x.fields)
Run Code Online (Sandbox Code Playgroud)

为什么会发生这种情况?

Nae*_*mul 5

我认为这与https://issues.scala-lang.org/browse/SI-3167 的情况相同

Scala 编译器错误:可堆叠特征和惰性值导致 StackoverflowException

trait Thing { def name: String }
trait Thing1 extends Thing { override lazy val name = "One" }
trait Thing2 extends Thing { abstract override lazy val name = super.name }
val t = new Thing with Thing1 with Thing2
t.name
Run Code Online (Sandbox Code Playgroud)

结果在java.lang.StackOverflowError.

你可以让它更相似。

trait Thing { def name: String = "" }
trait Thing1 extends Thing { override lazy val name = "One" }
trait Thing2 extends Thing { override lazy val name = super.name }
val t = new Thing with Thing1 with Thing2
t.name
Run Code Online (Sandbox Code Playgroud)

这也导致java.lang.StackOverflowError.

无论如何,这个错误修复他妈的被推迟了。

Added the Fix Version 'Scala 2.11.3'
Removed the Fix Version 'Scala 2.11.2' 

Added the Fix Version 'Scala 2.11.2'
Removed the Fix Version 'Scala 2.11.1' 

Added the Fix Version 'Scala 2.11.1-RC1'
Removed the Fix Version '2.11.1-RC1' 

Added the Fix Version '2.11.1-RC1'
Removed the Fix Version 'Scala 2.11.0-RC1' 

Added the Fix Version 'Scala 2.11.0-RC1'
Removed the Fix Version 'Scala 2.11.0-M8' 

Added the Fix Version 'Scala 2.11.0-M8'
Removed the Fix Version 'Scala 2.11.0-M7' 

Added the Fix Version 'Scala 2.11.0-M6'
Removed the Fix Version 'Scala 2.11.0-M4' 

Added the Fix Version 'Scala 2.11.0-M4'
Removed the Fix Version 'Scala 2.11.0-M3' 

Added the Fix Version 'Scala 2.11.0-M3'
Removed the Fix Version 'Scala 2.11.0-M2' 

...
Run Code Online (Sandbox Code Playgroud)

随着 2010 年报告的问题。

我建议不要使用lazy val调用super可堆叠特征的s 。