2009-11-09 60 views
8

爲什麼scalac(Scala編譯器)不優化尾遞歸?爲什麼在某些情況下scalac不能優化尾遞歸?

代碼和編譯器調用演示了此:

 
> cat foo.scala 
class Foo { 
def ifak(n: Int, acc: Int):Int = { 
    if (n == 1) acc 
    else ifak(n-1, n*acc) 
} 
} 

> scalac foo.scala 
> jd-gui Foo.class 
import scala.ScalaObject; 

public class Foo 
    implements ScalaObject 
{ 
    public int ifak(int n, int acc) 
    { 
    return ((n == 1) ? acc : 
     ifak(n - 1, n * acc)); 
    } 
} 
+1

請注意,JVM級別的tailcall優化是爲java 7貢獻的,請參閱http://wikis.sun.com/display/mlvm/TailCalls – 2009-11-09 11:25:52

回答

12

中的方法可以重寫不能是尾遞歸。試試這個:

class Foo { 
    private def ifak(n: Int, acc: Int): Int = { 
    if (n == 1) acc 
    else ifak(n-1, n*acc) 
    } 
} 
+0

+1原因是什麼? (我的意思是我可以想像,但我想知道) – OscarRyz 2010-12-09 19:48:26

+2

@OscarRyz:請參閱http://stackoverflow.com/questions/4785502/why-wont-the-scala-compiler-apply-tail-call-optimization-除非-A-方法-是-FINA – 2011-07-11 15:17:01

1

試試這個:

class Foo { 
    def ifak(n: Int, acc: Int):Int = { 
    if (n == 1) acc 
    else ifak(n-1, n*acc) 
    } 
} 

class Bar extends Foo { 
    override def ifak(n: Int, acc: Int): Int = { 
    println("Bar!") 
    super.ifak(n, acc) 
    } 
} 

val foobar = new Bar 
foobar.ifak(5, 1) 

注意ifak可能是遞歸的,但它可能沒有得到很好的。最後標記類或方法,它可能會做尾遞歸。

0

內部功能也符合總體擁有成本。

相關問題