当前位置:网站首页>有趣的 Kotlin 0x0E:DeepRecursiveFunction
有趣的 Kotlin 0x0E:DeepRecursiveFunction
2022-08-04 04:37:00 【AndroidKt】
前言
DeepRecursiveFunction 是 Kotlin 在 1.4.0 版本上尝试解决深度递归导致 StackOverflowError 问题的试行方案。在最新发布的 1.7.0 版本上正式 Stable。面对由于递归导致的栈溢出问题,一般我们采用两种解决办法:
- 增加栈大小
- 改写代码,采用非递归方式实现
Kotlin 通过定义 DeepRecursiveFunction 深度递归类型来实现非递归方式的改写。
官方建议:递归深度操作 1000 考虑使用 DeepRecursiveFunction。(Consider using deep recursive functions in your code where your recursion depth exceeds 1000 calls.)
语法
定义
public class DeepRecursiveFunction<T, R>(
internal val block: suspend DeepRecursiveScope<T, R>.(T) -> R
)
T为传入参数类型;R为输出结果类型;block函数体。
调用
public abstract suspend fun callRecursive(value: T): R
用于“递归”调用DeepRecursiveFunction
public operator fun DeepRecursiveFunction<*, *>.invoke(value: Any?): Nothing
操作符重载,以便 DeepRecursiveFunction 可以通过()操作符调用,当然也可以选择直接调用invoke函数。
看官方给出的示例对比,可能更直观一点。
示例
实现二叉树的深度计算:原始递归DeepRecursiveFunction。
原始递归
fun depth(t: Tree?): Int =
if (t == null) 0 else maxOf(
depth(t.left), // recursive call one
depth(t.right) // recursive call two
) + 1
DeepRecursiveFunction
val calculateDepth = DeepRecursiveFunction<Tree?, Int> {
t ->
if (t == null) 0 else maxOf(
callRecursive(t.left),
callRecursive(t.right)
) + 1
}
对比上面两种代码可以看出,开发者可以很容易从原始递归方式改写成 DeepRecursiveFunction 方式。这就是 Kotlin 希望达到的低开发成本效果。当开发者因采用原始递归方式时递归层级过深出现 StackOverflowError问题时, 简易调整为 DeepRecursiveFunction ,可以在避免大量改写代码的前提下帮助开发者快速解决栈溢出问题。
Run
fun main() {
// Generate a tree with a depth of 100_000
val deepTree = generateSequence(Tree(null, null)) {
prev ->
Tree(prev, null)
}.take(4).last()
println(calculateDepth(deepTree)) // 100000
println(depth(deepTree)) // 100000
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LPAOp9KH-1659446563474)(http://qiniu.fultter.club/image-20220731130252997.png)]
源码
关于 DeepRecursiveFunction 的源码全部集中于 DeepRecursive.kt文件中,主要包含三个类:
- DeepRecursiveFunction
- DeepRecursiveScope
- DeepRecursiveScopeImpl
具体的实现集中在 DeepRecursiveScopeImpl 类中,通过协程机制实现递归逻辑。
suspend 模拟向下压栈 ️,resume 模拟向上出栈 ️,实现类似递归调用的效果🪆。
结语
每一颗语法糖背后,总有几个 Kotlin 的工程师在为我们负重前行。🥸
边栏推荐
- 八年软件测试工程师带你了解-测试岗进阶之路
- 8.Haproxy 搭建Web集群
- Tensors - Application Cases
- 学会iframe并用其解决跨域问题
- 2022杭电多校联赛第五场 题解
- Explain detailed explanation and practice
- A Preliminary Study of RSS Subscription to WeChat Official Account-feed43
- 外卖店优先级
- manipulation of file contents
- How to simplify the automation of modern e-procurement?
猜你喜欢

This Thursday evening at 19:00, the fourth live broadcast of knowledge empowerment丨The realization of equipment control of OpenHarmony smart home project

深度学习环境配置
![[21 Days Learning Challenge] Image rotation problem (two-dimensional array)](/img/51/fb78f36c71e1eaac665ce9f1ce04ea.png)
[21 Days Learning Challenge] Image rotation problem (two-dimensional array)

if,case,for,while

企业直播风起:目睹聚焦产品,微赞拥抱生态

Eight guiding principles to help businesses achieve digital transformation success

七夕节,我用代码制作了表白信封

7-2 LVS+DR概述与部署

软件测试如何系统规划学习呢?

【C语言进阶】程序环境和预处理
随机推荐
7-1 LVS+NAT 负载均衡群集,NAT模式部署
深度学习21天——准备(环境配置)
七夕节,我用代码制作了表白信封
十一种概率分布
【机器学习】21天挑战赛学习笔记(一)
八年软件测试工程师带你了解-测试岗进阶之路
Hangdian Multi-School-Slipper- (tree map conversion + virtual point mapping)
mysql索引笔记
看DevExpress丰富图表样式,如何为基金公司业务创新赋能
帮助企业实现数字化转型成功的八项指导原则
缓存穿透、缓存击穿、缓存雪崩以及解决方案
使用serve搭建本地服务器
如何简化现代电子采购的自动化?
Significant differences between Oracle and Postgresql in PLSQL transaction rollback
什么是数字孪生智慧城市应用场景
Mockito unit testing
【21 Days Learning Challenge】Direct Insertion Sort
SQL injection in #, - +, - % 20, % 23 is what mean?
软件测试如何系统规划学习呢?
信息学奥赛一本通 1312:【例3.4】昆虫繁殖