代码之家  ›  专栏  ›  技术社区  ›  Thomas Cook

Kotlin递归堆栈溢出

  •  1
  • Thomas Cook  · 技术社区  · 7 年前

    我用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语言的最大堆栈深度是多少?我应该不递归地编写函数吗?

    1 回复  |  直到 7 年前
        1
  •  7
  •   Alexander Egger    7 年前

    这个 泰勒克 关键字告诉kotlin编译器使用尾部递归。因此,它将递归展开为一个循环,这样就可以消除 堆栈溢出错误 是的。

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

    所以当使用 泰勒克 编译器创建与以下函数匹配的内容:

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

    在此函数中,不再进行方法调用,因此不会将任何内容推送到堆栈中,我们将从 堆栈溢出错误 是的。

    注意,我们仍然可以进入一个无止境的循环!