scala尾递归装饰器不允许调用尾递归函数

scala tail recursion decorator not letting tail recursive function to be called

object FuncUtils {
  @tailrec
  def tryAll[T](funcs: (() => Any)*): Option[Any] = {
    if (funcs.isEmpty) {
      None
    } else {
      try {
        Some(funcs.head())
      } catch {
        case _: Throwable => FuncUtils.tryAll(funcs.tail: _*)
      }
    }
  }
}

为什么?在我看来,tryAll 是自包含的,迭代可以在不引用调用堆栈的情况下发生。

好的原因是因为我在调用函数之前指的是包含该方法的单例对象。

 FuncUtils.tryAll(funcs.tail: _*)

应该只是:

 tryAll(funcs.tail: _*)

我猜当我引用库时,scala 无法弄清楚它是递归的。

错误不可重现,您可以尝试提供更多上下文。

无论如何,我还建议您避免 Seq 用于 tail-recursive 算法 (您应该改用 List,并且try / catch(改用 Try Monad).
这是使用它重写您的代码。

import scala.util.{Try, Success, Failure}

object FuncUtils {
  def tryAll[T](funcs: (() => T)*): Option[T] = {
    @annotation.tailrec
    def loop(remaining: List[() => T]): Option[T] = remaining match {
      case Nil     => None
      case x :: xs => Try(x()) match {
        case Success(t) => Some(t)
        case Failure(_) => loop(remaining = xs)
      }
    }

    loop(remaining = funcs.toList)
  }
}

同样,正如 jwvh 所说,在这种情况下你真的不需要递归。

object FuncUtils {
  def tryAll[T](funcs: (() => T)*): Option[T] =
    funcs.iterator.map(f => Try(f())).collectFirst { case Success(t) => t }
}