简体   繁体   English

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)
}

Could someone please explain to me how does the above recursion function work in kotlin? 有人可以向我解释一下上面的递归函数在kotlin中是如何工作的吗?

I'll start saying that the tailrec keyword is used only as an optimization for the compiler that will try to express the function with a loop and not with recursion avoiding the risk of stack overflow . 我将开始说tailrec关键字仅用作编译器的优化,它将尝试用循环表示函数而不用递归来避免堆栈溢出的风险。

If we avoid recursion, the function could look to something like this: 如果我们避免递归,函数可能会看起来像这样:

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

There is a big risk when you use recursion in Java that is stackoverflow. 在Java中使用递归时存在很大的风险,即stackoverflow。 stack

As above link recursion works in Java. 如上所述,链接递归在Java中有效。 There will be some maximum size for stack, If our recursion function is going to infinite, then it will cross the max size and it leads to StackOverflow exception. 堆栈会有一些最大大小,如果我们的递归函数变为无穷大,那么它将超过最大大小并导致StackOverflow异常。 So avoid using recursion and use loop instead 因此,请避免使用递归并使用循环

Coming to the current problem. 来到当前的问题。 It's a special recursion which is Tail call . 这是一个特殊的递归,它是Tail调用 On that a function must call itself as the last operation it performs. 在那个函数上,函数必须将自己称为它执行的最后一个操作。 Tail calls can be implemented without adding a new stack frame to the call stack. 可以在不向调用堆栈添加新堆栈帧的情况下实现尾调用。 So there will not be any risk of StackOverflow. 因此StackOverflow不会有任何风险。 And it's supported in kotlin. 它在kotlin中得到了支持。

In Kotlin it uses tailrec modifier to show this special recursion. 在Kotlin中,它使用tailrec修饰符来显示这种特殊的递归。 You cannot use tail recursion when there is more code after the recursive call, and you cannot use it within try/catch/finally blocks. 当递归调用后有更多代码时,您不能使用尾递归,并且您不能在try / catch / finally块中使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM