Scala中的尾递归和返回语句

时间:2011-03-15 14:17:01

标签: scala

我在考虑这里提出的一个问题(Why does Scala require a return type for recursive functions?)以及如何改进代码。

无论如何,我在想这样的事情:

def simpledb_update(name: String, metadata: Map[String, String]) = {

  def inner_update(attempt: int): Unit = {
    try {
      db(config("simpledb_db")) += (name, metadata)
      return
    } catch {
      case e =>
        if (attempt >= 6) {
          AUlog(name + ": SimpleDB Failed")
          return
        }
    }
    inner_update(attempt+1)
  }

    inner_update(0)
}

或者

def simpledb_update(name: String, metadata: Map[String, String]) {

  def inner_update(attempt: int): Unit = {
    try {
      db(config("simpledb_db")) += (name, metadata)
    } catch {
      //Do I need the pattern match, since I don't
      // care what exception is thrown???
      if (attempt >= 6) {
        AUlog(name + ": SimpleDB Failed")
      } else {
        inner_update(attempt+1)
      }
    }
  }

  inner_update(0)
}

第二个实现是否仍然是尾递归(是第一个???)。当一个函数是尾递归的时候,当它不是时,我仍然有点朦胧。

3 个答案:

答案 0 :(得分:3)

是的,这两个例子仍然是尾递归的,你首先进行检查/处理,最后是递归调用。

The Jargon File简明扼要地说:Tail Recursion(n):如果你还没有厌倦它,请看尾递归。

答案 1 :(得分:2)

在Scala中,您可以向函数添加tailrecursive注释,然后编译器将检查它是否可以对函数进行尾调用优化。

答案 2 :(得分:0)

尾递归很容易理解 - 如果函数F的所有代码路径中的最后一个表达式只是一个函数调用,那么它是尾递归的。但它是否是Scala编译器优化的尾递归 - 取决于。 JVM不执行TCO这一事实意味着scala编译器具有魔力。

scalac可能无法优化的原因与多态性有关。如果可以在子类中重写Function,则scalac无法对其进行优化。

@Timo Rantalaiho,使用tailrec注释是验证TCO是否可以完成的最安全的方法。