lazy val seq: Unit = {
println("a")
seq
}
我们可以通过尾递归方式调用上面的表达式吗?
答案 0 :(得分:2)
我想你可以在这个意义上辩解,是的 - 在评估时,seq
会递归评估自己,而评估是最后一次执行的行动。
不管这是否可以被称为尾递归,但似乎没有太多意义。没有退出条件也没有,如果你尝试保持你的代码纯粹功能,可以有一个:没有参数,这意味着没有“状态”传递给更深层次的评估,没有任何东西可以测试以打破递归
此外,如果它确实是尾递归的,那么它不是Scala识别或支持的尾递归形式 - 评估seq
并得到StackOverflowError
。
答案 1 :(得分:0)
您可以询问REPL:
scala> import scala.annotation.tailrec
import scala.annotation.tailrec
scala> @tailrec
| def abc(a: Int): Int = a + abc(a+1)
<console>:10: error: could not optimize @tailrec annotated method abc: it contains a recursive call not in tail position
def abc(a: Int): Int = a + abc(a+1)
scala> @tailrec
| lazy val seq: Unit = {println("a"); seq}
seq: Unit = <lazy>
scala> seq
aa
a
...
(请原谅或更正某些命名错误)
据我所知,尾递归发生在你不需要上堆栈以获得前面的部分结果时,在我的例子中abc
被递归调用,但你确实需要上去堆栈获取以前的结果(a + abc(a + 1)
),如果它是abc(a+1)
它将是一个尾递归函数:
scala> @tailrec
| def abc(a: Int): Int = abc(a+1)
abc: (a: Int)Int
scala> abc(0)
...
您的val
定义不需要上堆,因为没有操作需要与堆叠期间累积的部分结果相结合。