let rec x1() = x1();()
let rec x2() = x2();;
调用x1();;生成堆栈溢出,同时调用x2();;导致程序无限期运行。这两个函数有什么区别?
答案 0 :(得分:7)
let rec x1() = x1();()
此函数不是尾递归。它自称为x1();当此调用返回时,该函数将返回一个单位()。
let rec x2() = x2();;
这个功能在最后调用自己;因此编译器可以执行尾调用优化 - 这意味着递归函数调用永远不会耗尽所有堆栈空间。
这个页面解释了尾递归:http://ocaml.org/learn/tutorials/if_statements_loops_and_recursion.html#Tailrecursion - 它是函数式编程语言使用的一种基本技术,因此我们可以使用递归来实现循环,而不会耗尽内存。
我在阅读Smashing The Stack For Fun And Profit时首先了解了进程堆栈;我仍然认为它对进程堆栈的所有内容有最好的描述。