07-尾递归函数
11.1.6 尾递归函数
Kotlin支持一种被称为尾递归的函数式编程风格,即允许使用递归函数来替代循环算法,用递归函数来编写,而无须考虑堆栈溢出(Stack Overflow)的风险。
所谓尾递归,就是在递归函数的调用过程中,在函数的最后部分调用函数本身。在调用递归函数时,经常会产生堆栈溢出的问题。为了解决这一问题,通常会使用tailrec修饰符标记该递归函数,经过tailrec修饰符标记的函数,会在编译过程中优化该递归函数。
tailrec fun findFixPoint(a: Double = 1.0): Double
= if(a == Math.cos(a)) a else findFixPoint(Math.cos(a))
上面这段代码的功能是计算余弦的不动点,该函数从1.0开始重复调用函数Math.cos(),直到结果不再改变为止,上面的这段代码等价于下面这种传统风格的写法。
private fun findFixPoint(): Double {
var x = 1.0
while (true) {
val y = Math.cos(x)
if (x == y) return x
x = y
}
}
如果在递归调用后仍有逻辑代码需要执行,则不能使用尾递归,而且尾递归不能用在try/catch/finally等代码块中。目前,尾递归函数只支持在JVM后端程序中进行调用。