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是自包含的,并且可以在不引用调用堆栈的情况下进行迭代。
答案 0 :(得分:3)
该错误无法重现,您可以尝试提供更多上下文。
无论如何,我还建议您避免使用Seq
进行尾部递归算法(您应改用List
)和try / catch
块< em>(改为使用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 }
}
答案 1 :(得分:0)
好的原因是因为在调用函数之前,我是指方法包含在其中的Singleton对象。
FuncUtils.tryAll(funcs.tail: _*)
应该是:
tryAll(funcs.tail: _*)
我想当我引用库时,scala不能弄清楚它的递归性。