Scala是否支持尾recursion优化?

Scala是否支持尾recursion优化?

正如其他海报所说,斯卡拉在编译时做了recursion优化。 也就是说,一个尾recursion函数被编译器转换成一个循环(一个方法调用被转换成一个跳转),从运行一个尾recursion函数时的栈跟踪中可以看出。

尝试以下代码片段:

def boom(n: Int): Nothing = if(n<=0) throw new Exception else boom(n-1) boom(10) 

并检查堆栈跟踪。 它只会显示一个调用函数的繁荣 – 因此编译的字节码不是recursion的。

有一个提议在JVM级别上实现尾调用 – 在我看来这是一个很好的事情,因为JVM可以进行运行时优化,而不是编译代码的时间优化 – 可能意味着更多灵活的尾recursion。 基本上, tailcall invoke行为与普通的方法invoke完全相同,但是在安全的情况下会tailcall invoke者的堆栈–JVM的规范说明了堆栈帧必须被保留,所以JIT必须做一些静态代码分析找出堆栈帧是否永远不会被使用。

目前的状况是原80% 。 我不认为Java 7会及时完成( invokedynamic具有更高的优先级,实现几乎完成),但是Java 8可能会看到它的实现。

在Scala 2.8中,您可以使用@tailrec来标记希望编译器优化的特定方法:

 import scala.annotation.tailrec @tailrec def factorialAcc(acc: Int, n: Int): Int = { if (n <= 1) acc else factorialAcc(n * acc, n - 1) } 

如果一个方法不能优化,你会得到一个警告。

Scala 2.7.x支持最终方法和本地函数的自recursion(自我调用函数)的尾调优化。

Scala 2.8也可能带有对蹦床的库支持,这是一种优化相互recursionfunction的技术。

关于Scalarecursion状态的大量信息可以在Rich Dougherty的博客中find 。

只有在函数是自recursion的非常简单的情况下。

certificate尾recursion能力。

看起来Scala 2.8可能会改善尾recursion识别。