这是我上一个问题的后续。
我想使用回复中的签名编写一个非递归retry
函数。请注意,此实现使用 view
作为延迟序列。
def withRetries[T](retries: Short)(fun: => T): Try[T] = {
(0 until retries).view.map(_ => Try(fun)).partition(_.isFailure) match {
case (a, b) if b.isEmpty => a.last
case (_, b) => b.head
}
}
有意义吗?你会如何改进它?
这符合您的要求...但是对于我的生活,我无法想象你为什么会想要那个......
def withRetries[T](retries: Int)(fun: => T) = (1 to retries)
.foldLeft[Try[T]](Failure(new Exception)) {
case (x@Success(_), _) => x
case _ => Try(fun)
}
基于 view
的解决方案很差,因为它执行fun
两次,即使第一次运行成功。我的新解决方案是:
def withRetries[T](retries: Short)(fun: => T): Try[T] = {
val stream = (0 until retries).toStream.map(_ => Try(fun))
stream.find(_.isSuccess) getOrElse stream.last
}
代码看起来不错,但我相信它的性能很差,因为Stream
.
另一方面,如果重试次数很少并且fun
耗时,则Stream
性能并不重要。