在Scala上键入不匹配以理解:scala.concurrent.Future

时间:2015-07-12 06:01:15

标签: scala future type-mismatch

我对Scala很新,请耐心等待。我有一大堆期货包裹在一个大数组中。期货已经通过几TB数据完成了他们的努力工作,在我的应用程序结束时,我想结束所有期货的结果,以便我能很好地呈现它们。

我拥有的期货集合属于以下类型:

Array[Future[List(String, String, String)]]

到目前为止,我所阅读的关于for-comprehension的所有内容都表明

val test: Seq[Seq[List[String]]] = Seq(Seq(List("Hello", "World"), List("What's", "Up")))

val results = for {
  test1 <- test
  test2 <- test1
  test3 <- test2
} yield test3

结果

results: Seq[String] = List(Hello, World, What's, Up)

按照同样的逻辑,我的意图是这样做,因为我最近发现Option,Try,Failure和Success可以被视为集合:

val futures = { ... } // Logic that collects my Futures

// futures is now Array[Future[List(String, String, String)]]

val results = for {
  // futureSeq as Seq[List(String, String, String]
  futureSeq <- Future.sequence(futures.toSeq)
  // resultSet as List(String, String, String)
  resultSet <- futureSeq
} yield resultset

但这不起作用。我似乎收到以下编译错误:

  

错误:(78,15)类型不匹配;
  found:Seq [List(String,String,String)]
  必需:scala.concurrent.Future [?]

     

resultSet&lt; - futureSeq                 ^

带有要求的部分: scala.concurrent.Future [?] 让我完全失望。我完全不明白为什么那里需要一个未来。

我通过REPL检查了所有对象的类型,通过调试和使用IntelliJ的类型检查。他们似乎证实我并不只是对我的类型感到困惑。

在任何人提到之前,是的,我知道for-comprehension是一堆地图,flatMaps和withFilters的语法糖。

1 个答案:

答案 0 :(得分:2)

for - 理解如何去除对flatMapmap的调用的详细信息非常重要。这段代码:

for {
  futureSeq <- Future.sequence(futures.toSeq)
  resultSet <- futureSeq
} yield resultset

或多或少地变成这样的东西:

Future.sequence(futures.toSeq).flatMap(futureSeq => futureSeq)

flatMap上的Future需要一个返回Future的函数,但您已经给它一个返回Seq[List[(String, String, String)]]的函数。

一般情况下,你不能在for中混合类型 - 理解(Option在序列理解中是一种由隐式转换支持的异常)。如果你的未来有<-箭头,那么<-箭头的其他所有箭头都需要来自未来。

你可能想要这样的东西:

val results: Future[Seq[(String, String, String)]] =
  Future.sequence(futures.toSeq).map(_.flatten)

然后你可以使用这样的东西:

import scala.concurrent.Await
import scala.concurrent.duration._

Await.result(results.map(_.map(doSomethingWithResult)), 2.seconds)

同步显示结果(阻塞直至完成)。