我正在阅读 Scala Cookbook ( http://shop.oreilly.com/product/0636920026914.do )

有一个与 Future use 相关的示例,涉及理解。

到目前为止,我对理解的理解是,当与一个集合一起使用时,它将产生另一个具有相同类型的集合。例如,如果每个 futureX 的类型为 Future[Int] ,则以下内容也应为 Future[Int] 类型:

for {
   r1 <- future1
   r2 <- future2
   r3 <- future3
} yield (r1+r2+r3)

有人能解释一下在这段代码中使用 <- 时到底发生了什么吗?
我知道如果它是一个生成器,它将通过循环获取每个元素。

最佳答案

首先关于理解。它被多次回答,它是对几个一元操作的抽象: mapflatMapwithFilter 。当您使用 <- 时,scalac 将此行脱糖为 monadic flatMap :
r <- monad 变成 monad.flatMap(r => ... )
它看起来像是一个命令式计算(monad 的全部内容),您将计算结果绑定(bind)到 r 。并且 yield 部分被脱糖为 map 调用。结果类型取决于 monad 的类型。
Future trait 有 flatMapmap 函数,所以我们可以用它来理解。在您的示例中可以将糖化为以下代码:

future1.flatMap(r1 => future2.flatMap(r2 => future3.map(r3 => r1 + r2 + r3) ) )

并行性放在一边

不言而喻,如果 future2 的执行依赖于 r1 那么你不能逃避顺序执行,但如果 future 的计算是独立的,你有两个选择。您可以强制执行顺序执行,或允许并行执行。您不能强制执行后者,因为执行上下文将处理此问题。
val res = for {
   r1 <- computationReturningFuture1(...)
   r2 <- computationReturningFuture2(...)
   r3 <- computationReturningFuture3(...)
} yield (r1+r2+r3)

将始终按顺序运行。可以通过脱糖轻松解释,之后仅在 flatMap 内部调用后续 computationReturningFutureX 调用,即
computationReturningFuture1(...).flatMap(r1 =>
    computationReturningFuture2(...).flatMap(r2 =>
        computationReturningFuture3(...).map(r3 => r1 + r2 + r3) ) )

然而,这能够并行运行,并且 for comprehension 聚合结果:
val future1 = computationReturningFuture1(...)
val future2 = computationReturningFuture2(...)
val future3 = computationReturningFuture3(...)

val res = for {
   r1 <- future1
   r2 <- future2
   r3 <- future3
} yield (r1+r2+r3)

关于Scala 的 "for comprehension"与 future ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19045936/

10-16 23:27