我正在阅读 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)
有人能解释一下在这段代码中使用
<-
时到底发生了什么吗?我知道如果它是一个生成器,它将通过循环获取每个元素。
最佳答案
首先关于理解。它被多次回答,它是对几个一元操作的抽象: map
、 flatMap
、 withFilter
。当您使用 <-
时,scalac 将此行脱糖为 monadic flatMap
:r <- monad
变成 monad.flatMap(r => ... )
它看起来像是一个命令式计算(monad 的全部内容),您将计算结果绑定(bind)到 r
。并且 yield
部分被脱糖为 map
调用。结果类型取决于 monad
的类型。Future
trait 有 flatMap
和 map
函数,所以我们可以用它来理解。在您的示例中可以将糖化为以下代码:
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/