将Future[Option[Future[Int]]]转换为Future[Option[Int]]。

3

在Scala中,从Future [Option [Future [Int]]]转换为Future [Option [Int]]的最干净的方法是什么?是否可能?


1
如果您决定走scalaz这条路,那么monad transformers就是非常好的工具。我认为OptionT [Task,Int]会对您有所帮助。相关链接:https://dev59.com/QmYq5IYBdhLWcg3wjBUM#14386670 - Chris Martin
3个回答

11

有两个嵌套的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 并没有扩展它。


1

最干净的方法可能是使用scalaz:

import scalaz.std.option._
import scalaz.std.scalaFuture._
import scalaz.syntax.traverse._

//assuming implicit execution context in scope

f.flatMap(_.sequence)

0
你正在寻找一种编程方法来摆脱某些问题,已经有了一些关于如何做到这一点的好答案,但是你应该退后一步,尝试不要陷入当前所处的问题中。请参考我在这里的答案: Get rid of Scala Future nesting,了解如何避免进入Future[X[Future[y]]类型签名,以便您不必想办法摆脱它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接