我已经使用过并阅读了关于@tailrec
注解的内容,以实现尾递归方法。我查看了许多解释它的链接。例如,它仅在自调用函数中起作用,并且不应该被覆盖等。
到处都提到编译器进行优化
。但编译器是通过什么魔法/概念使其成为尾递归的呢?对于下面的简单函数,编译器做了什么:
@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 }
的操作。应该可以通过机械化地将所有尾递归替换为转到函数体开头的goto语句来实现。 - huynhjl