ste*_*lla 4 recursion scala tail-recursion
我正在阅读M. Odersky的Scala编程,他说
像approximate这样自称为最后一个动作的函数叫做tail recursive.
所以,我试过这个:
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)
Run Code Online (Sandbox Code Playgroud)
但它会生成以下堆栈跟踪
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)
Run Code Online (Sandbox Code Playgroud)
这意味着它为每个递归调用生成一个新的堆栈帧.但最后一步是呼唤自己.什么是错的,如何让它尾递归?
为什么编译器不进行尾调用优化?
您可以尝试使用@tailrec注释标记方法.如果你这样做,编译将失败,并将告诉你为什么编译器无法优化它为尾递归:
Main.scala:12:错误:无法优化@tailrec带注释的方法测试:它既不是私有的也不是最终的,所以可以被覆盖
实际上,如果你制作方法final,它会按预期工作.