我正在阅读斯卡拉食谱(http://shop.oreilly.com/product/0636920026914.do)
有一个与未来使用有关的例子涉及到理解 .
到目前为止,我对理解的理解是,当与集合一起使用时,它将生成具有相同类型的另一个集合 . 例如,如果每个 futureX
的类型为 Future[Int]
,则以下类型也应为 Future[Int]
类型:
for {
r1 <- future1
r2 <- future2
r3 <- future3
} yield (r1+r2+r3)
有人可以解释一下在这段代码中使用 <-
时究竟发生了什么吗?我知道如果它是一个生成器,它将通过循环获取每个元素 .
3 回答
首先是为了理解 . 它在很多时候得到了回答,它是对几个monadic操作的抽象:
map
,flatMap
,withFilter
. 当你使用<-
时,scalac将这些行去掉monadicflatMap
:r <- monad
成monad.flatMap(r => ... )
它看起来像一个命令式计算(monad是什么),你将计算结果绑定到
r
. 并且yield
部分被打入map
电话 . 结果类型取决于monad
的类型 .Future
trait具有flatMap
和map
函数,因此我们可以使用它来理解它 . 在您的示例中可以将以下代码解压缩:搁置并存
不言而喻,如果
future2
的执行依赖于r1
,则无法逃避顺序执行,但如果将来的计算是独立的,则有两种选择 . 您可以强制执行顺序执行,也可以允许并行执行 . 您无法强制执行后者,因为执行上下文将处理此问题 .将始终按顺序运行 . 它可以通过desugaring轻松解释,之后后续的
computationReturningFutureX
调用仅在flatMaps中调用,即但是,这可以并行运行,并且for comprehension聚合结果:
要在这里详细说明这些现有答案,这是一个简单的结果,用于演示
for
理解是如何工作的 .它有点冗长的功能,但值得深入研究 .
一个给我们一系列整数的函数
一个给我们一系列字符的函数
使用这些函数调用 within 进行理解 .
对于以下这些行,我们可以看出所有函数调用都是同步的,即
createAsciiChars
函数调用是 not executed ,直到createIntegers
完成其执行 .在
for
comprehensions之外调用这些函数createAsciiChars
,createIntegers
将是异步执行 .如果可能,它允许
r1
,r2
,r3
并行运行 . 这可能是不可能的,这取决于有多少线程可用于执行Future计算,但是通过使用这种语法,您告诉编译器如果可能的话并行运行这些计算,然后在完成所有计算后执行yield()
.