scala的@tailrec
注释是否支持Option.fold
方法?
@tailrec
def test(a: Int): Int =
if (a > 10)
Option(true).fold(test(a - 1))(_ => test(a - 2))
else
-1
此代码导致错误:
无法优化@tailrec带注释的方法测试:它包含一个 递归调用不在尾部位置
这个问题可以通过模式匹配来解决,但我发现fold
看起来更清晰。
答案 0 :(得分:7)
当你想在Scala中编写尾递归函数时,你对尾递归函数的调用需要在最后一个位置(因此尾调用递归)。
在您的情况下,Option.fold
是最后一个,而Scala编译器无法确定fold
的结果始终是对test
的调用。
您可以使用TailCals
,使用fold
编写尾递归函数:
import scala.util.control.TailCalls._
def test(a: Int): TailRec[Int] =
if (a > 10) tailcall(Option(true).fold(test(a - 1))(_ => test(a - 2)))
else done(-1)
test(11).result // -1
如果您发现使用TailRec
比使用模式匹配更简洁,那么您需要:
def test(a: Int): Int =
if (a > 10) Option(true) match {
case Some(_) => test(a - 2)
case None => test(a - 1)
}
else -1