当前位置: 首页 > 知识库问答 >
问题:

静态编程语言递归堆栈溢出

虞航
2023-03-14

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

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

共有1个答案

谭新知
2023-03-14

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

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

在这个函数中,不再进行任何方法调用,因此没有任何内容被推送到堆栈中,我们从StackOverflower中保存。

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

 类似资料:
  • 我试图用OkHttp和Cucumber在静态编程语言中设置一个Spring启动项目,并且在运行Cucumber任务时遇到以下错误。如何修复? 还有build gradle kts片段 我看到了这个错误https://github.com/square/okio/issues/647看起来可能是它,并修复了这个build.gradle,我如何将其翻译为kotlinbuild.gradle.kts?

  • 让我们回到函数,进行更深入的研究。 我们的第一个主题是 递归(recursion)。 如果你不是刚接触编程,那么你可能已经很熟悉它了,那么你可以跳过这一章。 递归是一种编程模式,在一个任务可以自然地拆分成多个相同类型但更简单的任务的情况下非常有用。或者,在一个任务可以简化为一个简单的行为加上该任务的一个更简单的变体的时候可以使用。或者,就像我们很快会看到的那样,处理某些数据结构。 当一个函数解决一

  • 如图所示,https://stackoverflow.com/a/16639438/8949356,在Java中,当声明的类是公共类时,可以重写其函数 但是我想知道如何用静态编程语言编写完全相同的代码,我已经尝试了很多,但没有找到任何关于这个主题的东西。我可以在Java中去做这件事,但我的其余代码是用静态编程语言编写的,而且我不能一直带着这种怀疑;静态编程语言对我来说是一个很好的工具,我想学习它。

  • 我正在研究这个简单的问题来练习基本Kotlin,在递归返回行上遇到了堆栈溢出,代码如下: 我对tailrec的理解是,它应该将递归函数转换为迭代函数,而迭代函数不会受到这种崩溃的影响。如果我没有正确实现尾部递归,编译器应该会发出错误。 有人能解释一下为什么这会像标准递归调用一样在大输入上崩溃吗?

  • 上周我更新了Kotlin 1.5,昨天看到谷歌打算让Jetpack成为设计UI的首选选项后,我想做一些测试。 问题是将我的项目更新为静态编程语言1.5,当尝试构建项目时,我得到以下错误: 静态编程语言1.5与Jetpack Compose不兼容吗?在谷歌搜索问题后,我找到了版本,其中提到了Jetpack Compose,但不是以“不兼容”的方式。 你对此有任何答案吗?我应该使用吗?在这种情况下,我

  • 我是Kotlin开发的新手,我不知道如何处理这个问题。我将以下Kotlin数据类映射到MongoDB集合(Spring data MongoDB): 我想覆盖默认的 id 获取器并返回一个字符串而不是对象 Id。似乎“id”字段名称无法更改,因为我收到消息“不允许自定义id属性的字段名称!自定义名称不会被考虑!“,因此我无法使用始终建议的_id解决方案。 如何才能做到这一点?我错过了什么吗?