当前位置:网站首页>有趣的 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 的工程师在为我们负重前行。🥸
边栏推荐
- drools从下载到postman请求成功
- 中信证券网上开户怎么开的?安全吗?
- OpenGL绘制圆
- Significant differences between Oracle and Postgresql in PLSQL transaction rollback
- 帮助企业实现数字化转型成功的八项指导原则
- 【 observe 】 super fusion: the first mention of "calculate net nine order" evaluation model, build open prosperity of power network
- Metaverse "Drummer" Unity: Crazy expansion, suspense still exists
- 某母婴小程序加密参数解密
- How to dynamically add script dependent scripts
- 7-2 LVS+DR概述与部署
猜你喜欢
技术解析|如何将 Pulsar 数据快速且无缝接入 Apache Doris
【21天学习挑战赛】图像的旋转问题(二维数组)
Significant differences between Oracle and Postgresql in PLSQL transaction rollback
Simple operation of the file system
【源码】使用深度学习训练一个游戏
drools从下载到postman请求成功
【MD5】采用MD5+盐的加密方式完成注册用户和登录账号
How to simplify the automation of modern e-procurement?
转:管理是对可能性的热爱,管理者要有闯进未知的勇气
Deep learning -- CNN clothing image classification, for example, discussed how to evaluate neural network model
随机推荐
如何简化现代电子采购的自动化?
学会iframe并用其解决跨域问题
【流程图】
8. Haproxy builds a web cluster
Mockito unit testing
一文详解DHCP原理及配置
SQL injection in #, - +, - % 20, % 23 is what mean?
Explain detailed explanation and practice
How to simplify the automation of modern e-procurement?
2022软件测试面试题 最新字节跳动50道真题面试题 刷完已拿下15k 附讲解+答疑
Deep learning -- CNN clothing image classification, for example, discussed how to evaluate neural network model
How to automatically export or capture abnormal login ip and logs in elastic to the database?
SVM介绍以及实战
7-1 LVS+NAT 负载均衡群集,NAT模式部署
【C语言进阶】程序环境和预处理
Implementing a server-side message active push solution based on SSE
小程序 + 电商,玩转新零售
嵌入式数据库开发编程MySQL(全)
【21天学习挑战赛】图像的旋转问题(二维数组)
Reproduce 20-character short domain name bypass