Can';t重载Scala隐式类中的apply方法

Can';t重载Scala隐式类中的apply方法,scala,apply,implicit,Scala,Apply,Implicit,我正在用async和wait编写一个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) { resul

我正在用
async
wait
编写一个
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
  }
我的问题是,
为什么我不能使用名称
apply
而不是
convertTriedFuture
?scala编译器似乎不允许在隐式类中只使用
apply
方法


谢谢。

Scala只在找不到具有所需签名的现有方法时才开始寻找隐式转换。但是在
Try
companion对象中已经有一个合适的方法:
def apply[T](r:⇒ T) :尝试[T]
,这样Scala在
apply
中将
T
推断为
Future[Something]
,并且不检查隐式转换

此外,此实现将不起作用:

def convertTriedFuture[T](f: => Future[T]): Future[Try[T]] = 
  f.map(value => Try(value))
如果
Future
失败,则不会调用
map
函数,并从
wait
引发异常,
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 }

对潜在的性能问题进行评论非常有帮助。谢谢科尔玛。
result = await { block.recoverError }