2011-11-17 80 views
3

假设我有以下代码在Scala中可以保证尾递归优化吗?

def foo(x:Int):Unit = { 
    if (x == 1) println ("done") 
    else foo(scala.util.Random.nextInt(10)) 
} 

能够保证所有的编译器做尾递归优化?

+0

我不知道Scala保证你什么,但是在JVM的一般情况下并不实现尾递归。 (对于tailrec调用没有JVM字节码) –

+0

@Basile Starynkevitch:Scala可以编译简单的尾循环递归循环。一些JVM支持“自动”尾部递归,但不幸的是Oracle不支持。 – Landei

回答

12

是的。要知道肯定添加@tailrec注释您的方法。这会导致编译器在使用尾递归进行编译时发出错误。

@tailrec 
def foo(x:Int):Unit = { 
    if (x == 1) println ("done") 
    else foo(scala.util.Random.nextInt(10)) 
} 
+1

在Scala 2.8中,我必须执行'import scala.annotation.tailrec'。 – Jus12

+0

试着打破它。在方法的底部添加一个额外的(),以便在调用之后做些事情,但仍然返回单位。 –

+0

我的意思是说你的建议有效,我只需要添加导入。 – Jus12

3

没有,则Unit返回类型是无关紧要的。

scala> @tailrec def f(i: Int) { if (i >= 0) { println(i); f(i - 1) } } 
f: (i: Int)Unit 

但是:

scala> @tailrec def f(i: Int) { if (i >= 0) { f(i - 1); println(".") } } 
<console>:11: error: could not optimize @tailrec annotated method f: 
    it contains a recursive call not in tail position 

你需要有递归调用的最后一次通话,返回类型并不重要。

你在问题中的代码是好的,但问题的标题会误导。

+0

同意。我编辑了标题。感谢您的反例。 – Jus12