Scala @tailrec 折叠

Scala @tailrec with fold

scala 的 @tailrec 注解是否支持 Option.fold 方法?

@tailrec
def test(a: Int): Int =
  if (a > 10)
    Option(true).fold(test(a - 1))(_ => test(a - 2))
  else
    -1

此代码导致错误:

Could not optimize @tailrec annotated method test: it contains a recursive call not in tail position

这个问题可以通过模式匹配来解决,但我发现 fold 看起来干净多了。

当你想在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