我很困惑下面的代碼:代碼是人爲的,但我仍然認爲它是尾遞歸。編譯器不同意併產生一條錯誤消息:爲什麼在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