gpt4 book ai didi

java - 环绕具有不同签名的通用回调函数

转载 作者:行者123 更新时间:2023-11-29 05:02:21 24 4
gpt4 key购买 nike

我正在尝试学习 Scala,到目前为止它似乎是一门非常强大的语言,但有些事情似乎很难实现,可能只是我的学习曲线。我在网上研究了几天,但找不到一个好的解决方案来做我想做的事情。

我有多个方法(具有不同的签名,包括返回类型),我想在重试逻辑中将其包装起来。

我想继续调用一个方法预定的次数,直到该方法成功。

这是一个例子:

def downloadLocal(memory: Boolean, userName: Name, version: Int): Int

def downloadRemote(
memory: Boolean, userName: Name, masterNodeId: String, masterNodeId: String
): Pair(Int, Int)

我想将这两个方法包装在重试逻辑中。这是我对重试逻辑的尝试:

trait WithRetry{
def withRetry(retry :Int){
try{
callBack
}catch{
case exception:Throwable =>
if(retry>0){
logger.warn(exec+" method failed with an exception. retry number is:" + retry);
logger.warn(exception);
withRetry(retry-1)
}
else{
throw exception
}
}
}
def callBack():Any
}

我遇到的问题是我无法在重试逻辑中找到一种干净的方法来包装我的方法(downloadRemotedownloadLocal)。

有什么建议/想法吗?

最佳答案

你可以只定义一个泛型函数:

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

def retry[T](times: Int)(block: => T): T = Try(block) match {
case Success(result) => result
case Failure(e) =>
if (times > 0) {
logger.warn(s"method failed with an exception, retry #$times")
logger.warn(exception)
retry(times - 1)(block)
}
else throw e
}

这是一个尾递归函数,因此它与在 Java 中的 for 循环中调用该函数一样高效。

然而,更惯用的 Scala 会返回一个 Try :

def retry2[T](times: Int)(block: => T): Try[T] = 
Try(block) match {
case Failure(e) if (times > 0) =>
logger.warn(s"method failed with an exception, retry #$times")
logger.warn(exception)
retry2(times - 1)(block)
case other => other
}

两个版本都可以用作:

def failRandomly: Int = 
if (scala.util.Random.nextInt < 0.80) throw new Exception("boom")
else 1

scala> retry(2)(failRandomly)
res0: Int = 1
scala> retry(2)(failRandomly)
java.lang.Exception: boom // ...

scala> retry2(2)(failRandomly)
res1: scala.util.Try[Int] = Success(1)
scala> retry2(2)(failRandomly)
res2: scala.util.Try[Int] = Failure(java.lang.Exception: boom)

关于java - 环绕具有不同签名的通用回调函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31664012/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com