这是我之前question的后续内容。
我想使用reply中的签名编写非递归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
}
}
有意义吗? 你会如何改进它?
答案 0 :(得分:1)
这就是你所要求的......但对于我的生活,我无法想象为什么你会想要......
def withRetries[T](retries: Int)(fun: => T) = (1 to retries)
.foldLeft[Try[T]](Failure(new Exception)) {
case (x@Success(_), _) => x
case _ => Try(fun)
}
答案 1 :(得分:0)
基于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
性能无关紧要。