我已经使用并阅读了@tailrec
注释具有尾递归方法。我浏览了许多解释它的链接。例如,它仅在自调用函数时有效,并且不应被覆盖等。
到处都提到compiler optimizes
。但是编译器做了什么魔法/概念来使其成为尾递归。对于下面的简单函数,编译器会做什么:
@tailrec def fact(acc: Int, n: Int): Int = {
if (n <= 1) acc
else fact(n * acc, n - 1)
}
fact(1,10)
我的意思是它是否将其转换为一个循环,反复调用它然后返回最终值?是否有任何解释它的论文链接
除了我对您的问题的评论(在此处重新粘贴代码):
var acc = 1
var n = 10
start:
if (n <= 1) return acc
else {
acc = n * acc
n = n - 1
goto start
}
我尝试编译fact
我刚刚碰巧拥有的最近构建的方法scalac -Xprint:all
不知怎的,编译器发出了一个icode
文件。所以这确实说明了它如何优化尾部调用:
// methods
def fact(acc: Int (INT), n: Int (INT)): Int {
locals: value acc, value n, value _$this
startBlock: 1
blocks: [1,2,3,4,5]
1:
2 JUMP 2
2: // huynhjl's comment: IF condition is here
3 LOAD_LOCAL(value n)
3 CONSTANT(1)
3 CJUMP (INT)LE ? 3 : 4
3: // huynhjl's comment: first branch of IF, will return acc
3 LOAD_LOCAL(value acc)
3 JUMP 5
5:
2 RETURN(INT)
4: // huynhjl's comment: else branch of IF, update acc and n and jump back
4 LOAD_LOCAL(value n)
4 LOAD_LOCAL(value acc)
4 CALL_PRIMITIVE(Arithmetic(MUL,INT))
4 LOAD_LOCAL(value n)
4 CONSTANT(1)
4 CALL_PRIMITIVE(Arithmetic(SUB,INT))
4 STORE_LOCAL(value n)
4 STORE_LOCAL(value acc)
4 JUMP 2
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)