当前位置: 首页 > 知识库问答 >
问题:

反转 Scala 的未来

滕项明
2023-03-14

是否有可能“反转”Scala的未来?

有时候,未来成功的结果意味着错误。在这种情况下,翻转一个未来会很好,即调用一个返回未来的函数,如果最初的未来失败,则该函数以指定的值成功,如果最初的未来成功,则以指定的错误失败。

def flip[T](original: Future[T])(value: => T)(error: Throwable): Future[T] = ???

共有3个答案

颛孙天宇
2023-03-14

在 Scala 2.12 中,您将能够使用 transformtransformWith 来使这变得微不足道。

但在那之前,这应该能让你到达那里:

implicit class InvertFuture[T](val fut: Future[T]) extends AnyVal {
  def flip(recover: Throwable => T)(fail: T => Throwable)(implicit ec: ExecutionContext): Future[T] =
        fut.recover({ case t => recover(t) }).map(t => throw fail(t))
}

// And usage:

scala> Future(1).flip(_ => 2)(_ => throw new IllegalStateException("ohnoes!")) onComplete println
Failure(java.lang.IllegalStateException: ohnoes!)
马涵蓄
2023-03-14

我想你是在恢复恢复与构造之后。这是一个快速的REPL会话来展示它的用法。

$ scala
Welcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_45).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import scala.concurrent.Future
import scala.concurrent.Future

scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global

scala> val failFuture = Future(sys.error("BOOM"))
failFuture: scala.concurrent.Future[Nothing] = scala.concurrent.impl.Promise$DefaultPromise@6e06451e

scala> val defaultValue = 100
defaultValue: Int = 100

scala> val futureRecoveredWithDefaultFuture = failFuture.recoverWith { case e: RuntimeException => Future.successful(defaultValue) }
futureRecoveredWithDefaultFuture: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise$DefaultPromise@130161f7

scala> val futureRecoveredWithDefaultValue = failFuture.recover { case e: RuntimeException => defaultValue }
futureRecoveredWithDefaultValue: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise$DefaultPromise@3b69e7d1

检查这是否真的有效:

scala> import scala.concurrent.duration._
import scala.concurrent.duration._

scala> import scala.concurrent.Await
import scala.concurrent.Await

scala> val res1 = Await.result(futureRecoveredWithDefaultFuture, 1.second)
res1: Int = 100

scala> val res2 = Await.result(futureRecoveredWithDefaultValue, 1.second)
res2: Int = 100
咸昊昊
2023-03-14
  def craziness[A](future: Future[A])(default : => A)(error: Throwable)(implicit ec: ExecutionContext): Future[A] = {
    val p = Promise[A]()
    import scala.util.{Success, Failure, Try}
    future.onComplete {
      case _: Success[_] => p.failure(error)
      case _: Failure[_] => p.complete(Try(default))
    }
    p.future
  }

下面是一个repl会话,显示了它的工作原理:

scala> val f1 = craziness[String](Future("hello!"))("my crazy default")(new Throwable("boom"))
f1: scala.concurrent.Future[String] = scala.concurrent.impl.Promise$DefaultPromise@4d154ccd

scala> f1 onComplete { println }
Failure(java.lang.Throwable: boom)

scala> val f2 = craziness[String](Future(throw new Exception("boom!")))("my crazy default")(new Throwable("boom"))
f2: scala.concurrent.Future[String] = scala.concurrent.impl.Promise$DefaultPromise@1890516e

scala> f2 onComplete { println }
Success(my crazy default)

编辑:

为了完整起见,< code>def疯狂[A](future: Future[A])大概应该是< code>def疯狂[A](future: =

 类似资料:
  • 我有一个对象,我想将其转换为

  • 本文向大家介绍Scala将Scala集合转换为Java集合,反之亦然,包括了Scala将Scala集合转换为Java集合,反之亦然的使用技巧和注意事项,需要的朋友参考一下 示例 当您需要将集合传递到Java方法中时: 如果Java代码返回Java集合,则可以通过类似的方式将其转换为Scala集合: 请注意,这些是装饰器,因此它们仅将基础集合包装在Scala或Java集合接口中。因此,通话.asJa

  • 我正在阅读Scala Cookbook(http://shop.oreilly.com/product/0636920026914.do) 有一个与未来使用相关的例子,涉及理解。 到目前为止,我对理解的理解是,当与一个集合一起使用时,它会产生另一个相同类型的集合。例如,如果每个< code>futureX的类型为< code>Future[Int],则以下内容也应为< code>Future[In

  • 假设我有一个函数,它调用一个阻塞可中断操作。我想在超时的情况下异步运行它。也就是说,我想在超时到期时中断函数。 所以我正在尝试做这样的事情: 问题是 (1) 中的 可以为 null,因为 (2) 尚未将其设置为当前线程。在这种情况下,我想等到 设置完毕。最好的方法是什么?

  • 我有一个名为temp的Arraylist。ArrayList中有一些元素。我想反转这个Arraylist并将这个反转列表的值存储在另一个列表中。这是我的代码。 这一行有个错误。它说,所需的Arraylist变得无效。那么,如何将反向临时列表的值保存在另一个ArrayList中呢?是否可以将此保存在另一个1-D数组中?

  • 我希望像下面这样的代码可以等待这两种未来,但是没有。 我以为< code>seq.onComplete会在完成自身之前等待它们全部完成,但事实并非如此;它会导致: 在scala.concurrent.Future的源代码中有点难以遵循,我想知道如何实现等待(动态大小的)序列的所有原始未来的并行,或者这里可能有什么问题。 编辑:相关问题:https://worldbuilding.stackexch