DeepRecursiveFunction所在位置是kotlin.DeepRecursiveFunction,其相關用法介紹如下。

用法:

class DeepRecursiveFunction<T, R>

定義將堆棧保留在堆上的深度遞歸函數,這允許不使用實際調用堆棧的非常深度的遞歸計算。要啟動對此深度遞歸函數的調用,請使用其invoke 函數。根據經驗,如果遞歸超過一千次調用,則應該使用它。

DeepRecursiveFunction 采用 T 類型的一個參數並返回 R 類型的結果。 block 代碼定義了遞歸函數的主體。在此塊中,callRecursive 函數可用於對聲明的函數進行遞歸調用。 DeepRecursiveFunction 的其他實例也可以使用callRecursive 擴展名在此範圍內調用。

例如,看看下麵的遞歸樹類和這個樹的深度遞歸實例,它有 100K 個節點:

class Tree(val left: Tree? = null, val right: Tree? = null)
val deepTree = generateSequence(Tree()) { Tree(it) }.take(100_000).last()

可以定義一個常規遞歸函數來計算樹的深度:

fun depth(t: Tree?): Int =
    if (t == null) 0 else max(depth(t.left), depth(t.right)) + 1
println(depth(deepTree)) // StackOverflowError

如果為 deepTree 調用此 depth 函數,由於深度遞歸,它會生成 StackOverflowError。但是,depth 函數可以通過以下方式使用DeepRecursiveFunction 重寫,然後成功計算 depth(deepTree) 表達式:

val depth = DeepRecursiveFunction<Tree?, Int> { t ->
    if (t == null) 0 else max(callRecursive(t.left), callRecursive(t.right)) + 1
}
println(depth(deepTree)) // Ok

深度遞歸函數也可以通過callRecursive擴展使用堆棧的堆相互調用。例如,以下一對相互遞歸函數計算樹中偶數深度處的樹節點數。

val mutualRecursion = object {
    val even: DeepRecursiveFunction<Tree?, Int> = DeepRecursiveFunction { t ->
        if (t == null) 0 else odd.callRecursive(t.left) + odd.callRecursive(t.right) + 1
    }
    val odd: DeepRecursiveFunction<Tree?, Int> = DeepRecursiveFunction { t ->
        if (t == null) 0 else even.callRecursive(t.left) + even.callRecursive(t.right)
    }
}

參數

T- 函數參數類型。

R- 函數結果類型。

block- 函數體。