我正在阅读 M. Odersky 的《Scala 编程》一书,他说:
像 approximate 这样在最后调用自己的函数被称为尾递归。
于是,我尝试了这个例子:
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)
但它生成了以下堆栈跟踪信息
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)
这意味着每次递归调用都会生成一个新的堆栈帧。但最后一步是对自身的调用。有什么问题,如何使其成为尾递归?
为什么编译器不进行尾调用优化?