我正在阅读 M. Odersky 的 Programming in Scala ,他说



所以,我试过这个:

object Main extends App {
    implicit val mc = new MyClass(8)
    val ti = new TestImplct
    ti.test
}

class TestImplct {
  def test(implicit mc : MyClass): Unit = {
    println(mc.i)
    mc.i -= 1
    if(mc.i < 0){
      throw new IllegalArgumentException
    }
    test
  }
}

class MyClass(var i : Int)

IDEONE DEMO

但它会生成以下堆栈跟踪
 Exception in thread "main" java.lang.IllegalArgumentException
    at TestImplct.test(Main.scala:13)
    at TestImplct.test(Main.scala:15)
    at TestImplct.test(Main.scala:15)
    at TestImplct.test(Main.scala:15)
    at TestImplct.test(Main.scala:15)
    at TestImplct.test(Main.scala:15)
    at TestImplct.test(Main.scala:15)
    at TestImplct.test(Main.scala:15)
    at TestImplct.test(Main.scala:15)

这意味着它为每个递归调用生成一个新的堆栈帧。但最后一个 Action 是调用自己。有什么问题以及如何使其成为尾递归?

为什么编译器不做尾调用优化?

最佳答案

您可以尝试使用 @tailrec 注释标记该方法。如果你这样做,编译将失败,并会告诉你为什么编译器不能将其优化为尾递归:



事实上,如果你创建方法 final ,它会按预期工作。

关于scala - 为什么函数不是尾递归的?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39223783/

10-10 17:58
查看更多