Kotlin 递归

Kotlin recursion

fun fact(x: Int): Int{
    tailrec fun factTail(y: Int, z: Int): Int{
        if (y == 0) return z
        else return factTail(y - 1, y * z)
    }
    return factTail(x, 1)
}

谁能给我解释一下上面的递归函数在 kotlin 中是如何工作的?

我要开始说 tailrec 关键字仅用作编译器的优化,编译器将尝试用循环而不是递归来表达函数,从而避免 stack overflow 的风险.

如果我们避免递归,该函数可能看起来像这样:

 fun fact(x: Int): Int {
    var result = x
    for (i in x - 1 downTo 1) {
        result *= i
    }
    return result
 }

在Java中使用递归有很大的风险,那就是Whosebug。 stack

如上所述 link 递归适用于 Java。堆栈会有一些最大大小,如果我们的递归函数将无限大,那么它将超过最大大小并导致 Whosebug 异常。所以避免使用递归并使用循环代替

来到当前的问题。这是一个特殊的递归 Tail call。在这一点上,函数必须调用自身作为它执行的最后一个操作。无需向调用堆栈添加新的堆栈帧即可实现尾调用。所以不会有任何 Whosebug 的风险。它在 kotlin 中得到支持。

在 Kotlin 中,它使用 tailrec 修饰符来显示这种特殊的递归。当递归调用后有更多代码时,不能使用尾递归,并且不能在 try/catch/finally 块内使用它。