【问题标题】:Scala Future Type mismatch issueScala 未来类型不匹配问题
【发布时间】:2022-01-23 17:36:22
【问题描述】:

我在一个 for yield 场景中遇到了 Scala 和多个期货的问题。 f1 和 f2 都是期货。 f2 future 基于从 f1 future 获得的值。

val result = for {
    f1 <- Await.result(dao.findNode("nodeA"), 5 seconds)            // This returns back a MyNode class
    f2 <- if (f1 != None && f1.isUpAndRunning)
                Future { LookupResult(true, f1.varA, f1.varB) }
          else
                lk ? Lookup(sm.id, sm.("address"))
} yield(f1, f2)

取决于 f1 的结果,当我的 if 语句计算结果为 false 时执行 Lookup()(这需要一些时间并返回 LookupResult),或者我模仿默认的 LookupResult。

返回以下错误:

类型不匹配。必需:Option[B_],找到:Future[(MyNode, Any)]

我只是没有正确映射结果吗?例如我应该在某处使用 asInstanceOf 吗?无论我做什么我都无法编译它。

非常感谢各位。

【问题讨论】:

  • 未来for-comprehension 中的Await.result 看起来很可疑,目前还不清楚f1 != None &amp;&amp; f1.isUpAndRunning 在什么情况下可能有意义。不清楚你在问什么,缺少太多的上下文。请提供一个最小的孤立示例,该示例会产生与您要解决的问题类似的编译错误。
  • 严格来说,for 理解应该用于相同的MonadAwait.result 给你一个Option[A] (所以Option monad。你的if 案例给你一个Future[B],所以Future monad。我不知道你的 else 分支给你什么,但只是查看f1iff2 案例,您应该能够看到您正在理解Option 然后Future,那么为什么期望它能够工作?

标签: scala future


【解决方案1】:

您的dao.findNode 方法可能会导致Future[Option[MyNode]],因此Await.result 使f1 成为Option[MyNode]。不清楚你想要什么类型,但你可以用这个得到Future[(Option[MyNode], LookupResult)]

dao.findNode("nodeA"), 5.seconds)
  .flatMap { nodeOpt: Option[MyNode] =>
    nodeOpt.filter(_.isUpAndRunning)
      .map { node =>
        // node exists and is up and running
        val finalResult = nodeOpt -> LookupResult(true, node.varA, node.varB)

        // it's much more efficient in this scenario to use
        // Future.successful than Future { }
        Future.successful(finalResult)
      }
      .getOrElse {
        // node didn't exist, or wasn't up and running
        val lookupFut = lk ? Lookup(sm.id, sm.("address"))
        lookupFut.map { lookupResult =>
          nodeOpt -> lookupResult
        }
      }
  }

正在发生的事情的大致轮廓是:

  • 使用dao查找节点
  • 在我们获得(可能不存在的)节点时安排回调以检查它是否已启动并运行(在这种情况下,我们会短路到我们现在已知的最终结果),否则执行查找并构建最终结果,如果查找成功

使用Future.successful 是因为Future {} 几乎肯定会在线程上调度任务并完成未来比构造最终结果产生更多开销。

【讨论】:

  • 不完全清楚你在寻找什么,或者你是否有一些奇怪的(并且可能是不明智的)隐含在范围内与类型进行猴子。
猜你喜欢
  • 1970-01-01
  • 2020-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-27
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多