Kotlin 递归堆栈溢出

Kotlin recursion stack overflow

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

它将 运行 不确定的次数(因为我使用随机性来收敛进化算法中的解)。我经常遇到堆栈溢出。 Kotlin/JVM 种语言的最大堆栈深度是多少?我应该只写非递归函数吗?

tailrec 关键字告诉 Kotlin 编译器使用尾递归。因此它将递归展开为一个循环,这样您就可以摆脱 WhosebugError

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

因此,当使用 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)
    }
}

在此函数中,不再进行任何方法调用,因此不会将任何内容推送到堆栈,我们从 WhosebugError 中保存。

请注意,我们仍然可以运行进入死循环!