【发布时间】:2015-03-02 10:08:30
【问题描述】:
我对以下代码感到困惑:代码是人工的,但我仍然认为它是尾递归的。编译器不同意并产生错误信息:
@annotation.tailrec
def listSize(l : Seq[Any], s: Int = 0): Int = {
if (l.isEmpty) {
None.getOrElse( return s )
}
listSize(l.tail, s + 1)
}
上面的代码如何使尾部回避成为不可能?为什么编译器告诉我:
无法优化@tailrec 注解的方法listSize:它包含一个不在尾部位置的递归调用
类似的代码(return 在map 内)编译良好:
@annotation.tailrec
def listSize(l : Seq[Any], s: Int = 0): Int = {
if (l.isEmpty) {
Some(()).map( return s )
}
listSize(l.tail, s + 1)
}
即使是通过内联None.isEmpty得到的代码也能正常编译:
@annotation.tailrec
def listSize(l : Seq[Any], s: Int = 0): Int = {
if (l.isEmpty) {
if (None.isEmpty) {
return s
} else None.get
}
listSize(l.tail, s + 1)
}
另一方面,带有轻微修改映射的代码被编译器拒绝并产生错误:
@annotation.tailrec
def listSize(l : Seq[Any], s: Int = 0): Int = {
if (l.isEmpty) {
Some(()).map( x => return s )
}
listSize(l.tail, s + 1)
}
【问题讨论】:
-
我感觉编译器无法确定您的方法是否是尾递归,因为 return 语句,可能他是在防御并告诉您不能保证递归。
标签: scala recursion tail-recursion