我在考虑这里提出的一个问题(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)
}
第二个实现是否仍然是尾递归(是第一个???)。当一个函数是尾递归的时候,当它不是时,我仍然有点朦胧。
答案 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是否可以完成的最安全的方法。