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 块内使用它。
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 块内使用它。