首页 文章

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

提问于
浏览
4

我对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)] required:scala.concurrent.Future [?] resultSet < - futureSeq ^

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

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

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

1 回答

  • 2

    for -理解如何去调用 flatMapmap 的细节在这里很重要 . 这段代码:

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

    成为或多或少的东西:

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

    flatMapFuture 上需要一个返回 Future 的函数,但是你给它一个返回 Seq[List[(String, String, String)]] 的函数 .

    一般情况下,你不能在 for -comprehensions中混合类型(序列理解中的 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)
    

    同步呈现结果(阻塞直到完成) .

相关问题