尾递归 - 这将最佳地使用框架,我如何检查编译尾部是否递归?

时间:2013-03-29 19:31:57

标签: scala tail-recursion

在下面的代码中 - 相当简单的最大值和列表总和 - 我有一个在方法结束时调用的递归函数。 scala编译器会将其视为尾递归并优化堆栈帧使用吗?我如何知道/如何验证?

package example

import common._

object Lists {
  def sum(xs: List[Int]): Int = {

    def recSum(current: Int, remaining: List[Int]): Int = {
      if (remaining.isEmpty) current else recSum(current + remaining.head, remaining.drop(1))
    } 

    recSum(0, xs)
  }

  def max(xs: List[Int]): Int = {

    def recMax(current: Int, remaining: List[Int], firstIteration: Boolean): Int = {
      if(remaining.isEmpty){
        current
      }else{
        val newMax = if (firstIteration || remaining.head>current) remaining.head else current
        recMax(newMax, remaining.drop(1), false)
      }
    }

    if (xs.isEmpty) throw new NoSuchElementException else recMax(0, xs, true)
  }
}

1 个答案:

答案 0 :(得分:4)

在函数定义之前添加@tailrec以使编译器在非tailrecursive方法上导致错误:) 此外,当您通过编译器以这种方式对其进行优化时,您必须假设该函数与命令式循环(也称为for / while循环)一样高效。