[英]Can't overload apply method in Scala Implicit class
我正在使用async
和await
編寫retry
功能
def awaitRetry[T](times: Int)(block: => Future[T]): Future[T] = async {
var i = 0
var result: Try[T] = Failure(new RuntimeException("failure"))
while (result.isFailure && i < times) {
result = await { Try(block) } // can't compile
i += 1
}
result.get
}
Scala編譯器報告錯誤。 由於Try
沒有應用方法,因此需要使用Future[T]
。 所以我用隱式類解決了
implicit class TryCompanionOps(val t: Try.type) extends AnyVal {
// can't use `apply`!
def convertTriedFuture[T](f: => Future[T]): Future[Try[T]] =
f.map(value => Try(value))
}
// now we can convert Future[T] into Future[Try[T]] e.g,
await { Try.convertTriedFuture(block) }
我的問題是
為什么不能使用名稱apply
而不是convertTriedFuture
? 似乎scala編譯器不允許僅重載 隱式類中的 apply
方法。
謝謝。
Scala僅在找不到具有所需簽名的現有方法時才開始尋找隱式轉換。 但是在Try
伴隨對象中,已經有一個合適的方法: def apply[T](r: ⇒ T): Try[T]
,因此Scala apply
T
推斷為Future[Something]
,並且不檢查隱式轉換。
另外,此實現將無法正常工作:
def convertTriedFuture[T](f: => Future[T]): Future[Try[T]] =
f.map(value => Try(value))
如果Future
失敗,則不會調用map
的函數,並且從await
拋出Exception,並且async
立即導致失敗的Future
。 因此,使用此實現,該函數實際上不會重試。
您需要類似:
def convertTriedFuture[T](f: => Future[T]): Future[Try[T]] =
f.map(Success.apply).recover { case e => Failure(e) }
另外,我認為,在期貨中定義此恢復方法可能更簡潔:
implicit class FutureAdditionalOps[T](f: Future[T]) {
def recoverError: Future[Try[T]] =
f.map(Success.apply).recover { case e => Failure(e) }
}
然后你可以
result = await { block.recoverError }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.