当前位置:嗨网首页>书籍在线阅读

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后端程序中进行调用。