未来[期权[未来[Int]]]到未来[期权[Int]]
Future[Option[Future[Int]]] to Future[Option[Int]]
Scala 中从 Future[Option[Future[Int]]]
转换为 Future[Option[Int]]
的最简洁的方法是什么?有可能吗?
有两个嵌套的 Future
可以合并为一个,因此需要 flatMap
。
def flatten[A](f: Future[Option[Future[A]]]): Future[Option[A]] =
f.flatMap({
case None => Future.successful(None)
case Some(g) => g.map(Some(_))
})
或者,更简洁地说:
def flatten[A](f: Future[Option[Future[A]]]): Future[Option[A]] =
f.flatMap(o => Future.sequence(o.toSeq).map(_.headOption))
感谢@lmm 对此想法的回答。理想情况下,这可以写成 f.flatMap(Future.sequence)
,但不幸的是 sequence
期望 TraversableOnce
,Option
不会扩展。
最干净的方法可能是使用 scalaz:
import scalaz.std.option._
import scalaz.std.scalaFuture._
import scalaz.syntax.traverse._
//assuming implicit execution context in scope
f.flatMap(_.sequence)
你问的是如何通过编码摆脱一些纸袋,你已经得到了一些关于如何做到这一点的很好的答案,但是你应该退后一步,尽量不要进入你所在的纸袋目前在。在这里查看我的回答:Get rid of Scala Future nesting 关于如何避免进入 Future[X[Future[y]] 类型签名,这样您就不必弄清楚如何退出它。
Scala 中从 Future[Option[Future[Int]]]
转换为 Future[Option[Int]]
的最简洁的方法是什么?有可能吗?
有两个嵌套的 Future
可以合并为一个,因此需要 flatMap
。
def flatten[A](f: Future[Option[Future[A]]]): Future[Option[A]] =
f.flatMap({
case None => Future.successful(None)
case Some(g) => g.map(Some(_))
})
或者,更简洁地说:
def flatten[A](f: Future[Option[Future[A]]]): Future[Option[A]] =
f.flatMap(o => Future.sequence(o.toSeq).map(_.headOption))
感谢@lmm 对此想法的回答。理想情况下,这可以写成 f.flatMap(Future.sequence)
,但不幸的是 sequence
期望 TraversableOnce
,Option
不会扩展。
最干净的方法可能是使用 scalaz:
import scalaz.std.option._
import scalaz.std.scalaFuture._
import scalaz.syntax.traverse._
//assuming implicit execution context in scope
f.flatMap(_.sequence)
你问的是如何通过编码摆脱一些纸袋,你已经得到了一些关于如何做到这一点的很好的答案,但是你应该退后一步,尽量不要进入你所在的纸袋目前在。在这里查看我的回答:Get rid of Scala Future nesting 关于如何避免进入 Future[X[Future[y]] 类型签名,这样您就不必弄清楚如何退出它。