在Scala-Akka期货中,map和flatMap的区别是什么?

在Scala-Akka期货中,map和flatMap的区别是什么?,scala,akka,Scala,Akka,在普通的Scala中,map和flatMap的不同之处在于flatMap将返回一个整平为列表的数据表。 然而在Akka文档中,map和flatMap似乎做了一些不同的事情 它说“通常情况下,这非常有效,因为这意味着运行快速函数的开销非常小。如果函数可能需要花费大量时间来处理,则最好同时执行此操作,为此,我们使用flatMap:” 有人能解释一下Akka futures中map和flatMap的区别吗 有人能解释一下Akka futures中map和flatMap的区别吗 类型,基本上: fla

在普通的Scala中,map和flatMap的不同之处在于flatMap将返回一个整平为列表的数据表。 然而在Akka文档中,map和flatMap似乎做了一些不同的事情

它说“通常情况下,这非常有效,因为这意味着运行快速函数的开销非常小。如果函数可能需要花费大量时间来处理,则最好同时执行此操作,为此,我们使用flatMap:”

有人能解释一下Akka futures中map和flatMap的区别吗

有人能解释一下Akka futures中map和flatMap的区别吗

类型,基本上:

flatMap[A](f: T => Future[A]): Future[A] 

map[A](f: T => A): Future[A] 
在“普通”Scala中(如您所说),map和flatMap与列表无关(例如,选中选项)

亚历克赛给了你正确的答案。现在,如果您想知道为什么我们需要这两种语言,那么在编写futures时,它允许使用nice
for
语法。假设:

val future3 = for( x <- future1;
                   y <- future2 ) yield ( x + y )
val future3 = future1.map( x => future2.map( y => x+y ) )
如果遵循方法签名,您应该看到表达式将返回类型为
Future[A]
的内容

假设现在只使用map,编译器可以执行以下操作:

val future3 = for( x <- future1;
                   y <- future2 ) yield ( x + y )
val future3 = future1.map( x => future2.map( y => x+y ) )
但是,结果应该是
Future[Future[A]]
类型。这就是为什么你需要把它弄平

为了了解背后的概念,这里是我读过的最好的介绍之一:


我在这里粘贴这两种方法的实现。 英语术语的区别如下 并将函数结果作为新的未来返回

         /** Creates a new future by applying a function to the successful result of
       *  this future. If this future is completed with an exception then the new
       *  future will also contain this exception.
       *
       *  $forComprehensionExamples
       */
      def map[S](f: T => S)(implicit executor: ExecutionContext): Future[S] = { // transform(f, identity)
        val p = Promise[S]()
        onComplete { v => p complete (v map f) }
        p.future
      }

      /** Creates a new future by applying a function to the successful result of
       *  this future, and returns the result of the function as the new future.
       *  If this future is completed with an exception then the new future will
       *  also contain this exception.
       *
       *  $forComprehensionExamples
       */
      def flatMap[S](f: T => Future[S])(implicit executor: ExecutionContext): Future[S] = {
        import impl.Promise.DefaultPromise
        val p = new DefaultPromise[S]()
        onComplete {
          case f: Failure[_] => p complete f.asInstanceOf[Failure[S]]
          case Success(v) => try f(v) match {
            // If possible, link DefaultPromises to avoid space leaks
            case dp: DefaultPromise[_] => dp.asInstanceOf[DefaultPromise[S]].linkRootOf(p)
            case fut => fut.onComplete(p.complete)(internalExecutor)
          } catch { case NonFatal(t) => p failure t }
        }
    p.future
   }
从实现上看,区别在于flatMap实际上在承诺完成时调用带有结果的函数

case Success(v) => try f(v) match 

对于一篇好文章,请阅读:http//danielwestheide.com/blog/2013/01/16/the-neophytes-guide-to-scala-part-9-promises-and-futures-in-practice.html

我认为这有助于更好地理解它-为什么我们使用flatMap我没有意识到展平可以展平类型,我的想法是它将对象列表展平为一个列表。所以,从我的“旧”想法来看,我认为它只是走到了列表上,并将其展平。实际上,展平可以展平类型,正如您所说,Future[Future[A]]类似于List[List[A]]。一旦我迈出这一步,我就能更好地理解它。非常感谢!特别是对于这个职位!那个“分号”让我大吃一惊!确切地说,当你有一个返回未来[a]的方法时,这是有意义的,但你不是得到未来[a],而是想要未来[a]。如果你想知道更多关于
map
flatMap
的设计原则,这些原则植根于Monad抽象,我建议Scala的创建者Martin Odersky做这个讲座