为什么无限递归在F#中没有遇到堆栈溢出异常?

Ama*_*ant 6 .net f# functional-programming

我知道这与人们在询问堆栈溢出问题时遇到的问题有些相反,但如果我创建一个函数并按如下方式调用它,我从未收到任何错误,应用程序只是研磨了我的核心CPU直到我强制退出它:

let rec recursionTest x =
    recursionTest x

recursionTest 1
Run Code Online (Sandbox Code Playgroud)

当然我可以改变它,所以它实际上做了这样的事情:

let rec recursionTest (x: uint64) =
    recursionTest (x + 1UL)

recursionTest 0UL
Run Code Online (Sandbox Code Playgroud)

这样我偶尔会在我的代码中放一个断点,看看x的值很快就会上升,但它仍然没有抱怨.F#不介意无限递归吗?

Lee*_*Lee 9

你的recursionTest函数是尾递归的,这意味着所有递归调用都发生在'尾部位置',即作为函数中的最后一个动作.这意味着F#编译器不需要为递归调用分配新的堆栈帧,因此不会发生堆栈溢出.

尾递归是尾调用的一个特例,尾调用本身而不是其他一些函数.