简体   繁体   English

Kotlin递归堆栈溢出

[英]Kotlin recursion stack overflow

I have written this recursive function in Kotlin: 我已经在Kotlin中编写了此递归函数:

fun recursive(target: String, population: Population, debugFun: (String) -> Unit) : Population {
    if (population.solution(target).toString() == target) {
        return population
    }
    debugFun.invoke(population.solution(target).toString())
    return recursive(target, population.evolve(target), debugFun)
}

It will run an indeterminate amount of times (because I'm using randomness to converge on solution in evolutionary algorithm). 它将运行不确定的时间(因为我正在使用随机性来收敛进化算法的解)。 I am frequently getting stack overflow. 我经常遇到堆栈溢出。 What is the maximum stack depth for Kotlin/JVM languages? Kotlin / JVM语言的最大堆栈深度是多少? Should i just write the function non recursively? 我应该以非递归方式编写函数吗?

The tailrec keyword tells the Kotlin compiler to use tail recursion. tailrec关键字告诉Kotlin编译器使用尾部递归。 It therefore unrolls the recursion into a loop and this way you get rid of the StackOverflowError . 因此,它将展开递归循环到循环中,这样您就摆脱了StackOverflowError

tailrec fun recursive(target: String, population: Population, debugFun: (String) -> Unit) : Population {
    if (population.solution(target).toString() == target) {
        return population
    }
    debugFun.invoke(population.solution(target).toString())
    return recursive(target, population.evolve(target), debugFun)
}

So when using tailrec the compiler creates something which matches to following function: 因此,在使用tailrec时 ,编译器会创建与以下功能匹配的内容:

fun recursive(target: String, population: Population, debugFun: (String) -> Unit) : Population{
    var tmp = population

    while (true) {
        if (tmp.solution(target).toString() == target) {
            return tmp
        }
        debugFun.invoke(population.solution(target).toString())
        tmp = tmp.evolve(target)
    }
}

In this function no method calls are made any more therefore nothing gets pushed to the stack and we are save from StackOverflowError . 在此函数中,不再进行任何方法调用,因此没有任何内容被压入堆栈,因此我们从StackOverflowError中保存。

Note that we can still run into an endless loop! 请注意,我们仍然会陷入无尽的循环!

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

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