我很困惑下面的代码:代码是人为的,但我仍然认为它是尾递归。编译器不同意并产生一条错误消息:为什么在getOrElse中返回使尾部递归不可能?
@annotation.tailrec
def listSize(l : Seq[Any], s: Int = 0): Int = {
if (l.isEmpty) {
None.getOrElse(return s)
}
listSize(l.tail, s + 1)
}
上面的代码如何使tail tail recusion不可能?为什么编译器告诉我:
could not optimize @tailrec annotated method listSize: it contains a recursive call not in tail position
类似的代码(与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语句的尾递归,可能他是防御性的,告诉你递归不能保证。 – 2015-03-02 10:28:04