正如其他发帖者所说,Scala 在编译时进行尾递归优化。也就是说,尾递归函数被编译器转换为循环(方法调用转换为跳转),从运行尾递归函数时的堆栈跟踪可以看出。
尝试以下代码片段:
def boom(n: Int): Nothing = if(n<=0) throw new Exception else boom(n-1)
boom(10)
并检查堆栈跟踪。它将仅显示对函数oom的一次调用 - 因此编译后的字节码不是递归的。
有一个提案正在流传在 JVM 级别实现尾调用- 在我看来,这是一件很棒的事情,因为这样 JVM 就可以进行运行时优化,而不仅仅是代码的编译时优化 - 并且可能意味着更灵活的尾递归。基本上是一个tailcall invoke
其行为与普通方法完全相同invoke
但是在安全的情况下会丢弃调用者的堆栈 - JVM 的规范规定必须保留堆栈帧,因此 JIT 必须进行一些静态代码分析以查明堆栈帧是否永远不会被保留用过的。
它目前的状态是原型 80%。我认为 Java 7 不会及时完成(invokedynamic
具有更高的优先级,并且实现已接近完成),但 Java 8 可能会实现它。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)