我正在阅读Akka流的文档,我遇到了mapConcat运算符,就像flatMap一样(至少在概念层面).
这是一个简单的例子:
scala> val src = Source.fromFuture(Future.successful(1 to 10)) src: akka.stream.scaladsl.source[scala.collection.immutable.Range.Inclusive,akka.NotUsed] = Source(SourceShape(FutureSource.out(51943878)))
我期待源的类型是:
akka.stream.scaladsl.source[Future[scala.collection.immutable.Range.Inclusive],akka.NotUsed]
为什么不是这样?
我对每行的类型的理解如下所示:
Source .fromFuture(Future.successful(1 to 10)) // Source[Future[Int]] .mapConcat(identity) // Source[Int] .runForeach(println)
但上面例子中的Source类型并不是我想象的那样!
解决方法
Source.fromFuture的签名是:
def fromFuture[O](future: Future[O]): Source[O,NotUsed]
在您的示例中,O的类型为scala.collection.immutable.Range.Inclusive,因此Source.fromFuture的返回类型为:
Source[scala.collection.immutable.Range.Inclusive,NotUsed]
Scala docs
这是一个演示map和mapConcat之间区别的例子:
def f: Future[List[Int]] = Future.successful((1 to 5).toList) def g(l: List[Int]): List[String] = l.map(_.toString * 2) Source .fromFuture(f) .mapConcat(g) // emits 5 elements of type Int .runForeach(println) Source .fromFuture(f) .map(g) // emits one element of type List[Int] .runForeach(println)