簡體   English   中英

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編譯器使用尾部遞歸。 因此,它將展開遞歸循環到循環中,這樣您就擺脫了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)
}

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

在此函數中,不再進行任何方法調用,因此沒有任何內容被壓入堆棧,因此我們從StackOverflowError中保存。

請注意,我們仍然會陷入無盡的循環!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM