函数式编程中,重要的概念 尾递归:
当一个函数 在最后调用 自身,称为 尾递归,是一种特殊的递归函数。
Kotlin 使用 tailrec
声明尾递归函数,可以避免 StackOverflowError
的风险。
原理是:通过编译器优化 为 循环 或 GOTO 跳转,代替 原来递归调用。
在JVM中,每次方法调用时,都会产生新的栈帧(stack frame),消耗栈内存。当 调用层级过多时,就会产生
StackOverflowError
错误。
举例
计算 1 ~ N 的数之和。
tailrec fun sum(top: Long, initValue: Long): Long {
return if (top <= 0) {
initValue
} else {
sum(top - 1, initValue + top)
}
}
fun main(args: Array<String>) {
// 计算 100万 数字累加之和
println("sum: ${sum(1_000_000L, 0)}")
}
说明:
1. idea
查看 编译代码,Show Kotlin Bytecode
-> Decompile
:
2. 尝试把 tailrec
去掉,运行会 java.lang.StackOverflowError
错误
文档
- Tail recursive functions | Kotlin
- Tail call