我正在阅读Scala Cookbook(http://shop.oreilly.com/product/0636920026914.do)
有一个与未来使用相关的例子,涉及理解。
到目前为止,我对理解的理解是,当与一个集合一起使用时,它会产生另一个相同类型的集合。例如,如果每个< code>futureX的类型为< code>Future[Int],则以下内容也应为< code>Future[Int]类型:
for {
r1 <- future1
r2 <- future2
r3 <- future3
} yield (r1+r2+r3)
有人能解释一下使用时到底发生了什么吗
如果可能的话,它允许r1
、r2
和r3
并行运行。这可能是不可能的,这取决于有多少线程可用于执行未来的计算,但通过使用此语法,您可以告诉编译器在可能的情况下并行运行这些计算,然后在所有计算完成后执行yield()
。
在这里详细阐述这些现有答案,一个简单的结果来演示理解是如何工作的
。
它的功能有点长,但它们值得研究。
一个函数,它给我们一个整数范围
scala> def createIntegers = Future{
println("INT "+ Thread.currentThread().getName+" Begin.")
val returnValue = List.range(1, 256)
println("INT "+ Thread.currentThread().getName+" End.")
returnValue
}
createIntegers: createIntegers: scala.concurrent.Future[List[Int]]
给我们一系列字符的函数
scala> def createAsciiChars = Future{
println("CHAR "+ Thread.currentThread().getName+" Begin.")
val returnValue = new ListBuffer[Char]
for (i <- 1 to 256){
returnValue += i.toChar
}
println("CHAR "+ Thread.currentThread().getName+" End.")
returnValue
}
createAsciiChars: scala.concurrent.Future[scala.collection.mutable.ListBuffer[Char]]
为了便于理解,在中使用这些函数调用。
scala> val result = for{
i <- createIntegers
s <- createAsciiChars
} yield i.zip(s)
Await.result(result, Duration.Inf)
result: scala.concurrent.Future[List[(Int, Char)]] = Future(<not completed>)
对于下面的这些行,我们可以确定所有的函数调用都是同步的,也就是说,在< code>createIntegers完成其执行之前,不会执行< code>createAsciiChars函数调用。
scala> INT scala-execution-context-global-27 Begin.
INT scala-execution-context-global-27 End.
CHAR scala-execution-context-global-28 Begin.
CHAR scala-execution-context-global-28 End.
在< code>for理解之外调用这些函数< code > createscichars 、< code>createIntegers将是异步执行。
首先是理解。在SO上回答了很多很多次,它是对几个一元操作的抽象:map
,flatMap
,withFilter
。当您使用时
r
它看起来像一个命令式计算(monad是关于什么的),您将计算结果绑定到
r
。产量
部分被解压缩到map
调用中。结果类型取决于monad
的类型。
和< code>map函数,所以我们可以用它来理解。在你的例子中可以解糖成下面的代码:< code>Future
trait有一个< code>flatMap
future1.flatMap(r1 => future2.flatMap(r2 => future3.map(r3 => r1 + r2 + r3) ) )
不言而喻,如果未来2
的执行取决于r1
,则无法避免顺序执行,但如果未来的计算是独立的,则有两种选择。您可以强制顺序执行,也可以允许并行执行。您不能强制后者,因为执行上下文将处理此问题。
val res = for {
r1 <- computationReturningFuture1(...)
r2 <- computationReturningFuture2(...)
r3 <- computationReturningFuture3(...)
} yield (r1+r2+r3)
将始终按顺序运行。它可以很容易地用去加法来解释,之后后续的计算返回未来X
调用仅在平面图内部调用,即。
computationReturningFuture1(...).flatMap(r1 =>
computationReturningFuture2(...).flatMap(r2 =>
computationReturningFuture3(...).map(r3 => r1 + r2 + r3) ) )
但是,这能够并行运行,并且用于理解聚合结果:
val future1 = computationReturningFuture1(...)
val future2 = computationReturningFuture2(...)
val future3 = computationReturningFuture3(...)
val res = for {
r1 <- future1
r2 <- future2
r3 <- future3
} yield (r1+r2+r3)
我想在我的play scala Web应用程序中进行错误处理。 我的应用程序与数据库对话以获取一些行,它遵循以下流程。 < li >首先调用数据库以获取一些数据 < li >使用第一次调用中的数据从数据库中提取其他数据 < li >使用从最近两次db调用中收到的数据形成响应。 下面是我的伪代码。 以上理解中的每一个方法都返回一个未来,这些方法的签名如下。 在以下情况下,我该如何进行错误/故障处理
任务是实现递归方法,返回 Future 并且由于这一部分("在其他递归(结果::: res,尝试1)")代码失败与错误,因为它期望未来[Seq[结果]],但实际上返回未来[对象]。 据我所知,问题在于yield块内的表达式必须返回Seq[Result],以便将来由Monad进行后续包装。但是“递归(结果::res,尝试1)”将返回未来。因此,不是预期的Seq[Result]收益率,而是包含未来的[
我有两个函数返回期货。我正试图使用for-yield理解将第一个函数的修改结果输入到另一个函数中。 此方法有效: 然而,我对“如果”在那里不满意,似乎我应该能够使用地图。 但是当我尝试使用地图时: 我得到一个编译错误: 我尝试了一些变化,但没有发现任何有吸引力的工作。有人能提出更好的理解和/或解释我的第二个例子的错误吗? 下面是一个最小但完整的Scala 2.10可运行示例:
是否有可能“反转”Scala的未来? 有时候,未来成功的结果意味着错误。在这种情况下,翻转一个未来会很好,即调用一个返回未来的函数,如果最初的未来失败,则该函数以指定的值成功,如果最初的未来成功,则以指定的错误失败。
我有一些函数返回带有未来的元组元素列表(Int, Int)。为简单起见,我将定义两个未来 我想用下面的标准过滤并获取这两个未来列表中的元素。 在第二个位置包含相同元素的元组 在此方案中,输出应为 我可以用普通的列表(没有未来)来做这件事,比如下面的理解 如何与期货一起做?
Scala使用什么模式来处理这种情况: 你有很多未来(它们可以是任何东西,但为了举例…) 你有一个返回未来的函数 我想做这样的事情: 我想返回一个值,但是我在rent语句中调用foF,我会得到一个