【问题标题】:Using For Comprehension in Scala to only flatMap Future[T] after an If Test在 Scala 中使用 For Comprehension 在 If 测试后仅使用 flatMap Future[T]
【发布时间】:2019-03-24 12:45:04
【问题描述】:

我在使用 if 语句时需要帮助,只有在处理期货的理解中测试为假时才应该运行该语句。我是 scala 的新手,使用 this blog post 作为我的向导。

代码是

  for {
      emptyResults: Boolean = areResultsEmpty(content)
      resp <- getResp(content) if !emptyResults
      } yield resp

如果emptyResults 为真,则getResp() 会引发错误,但在上述情况下,即使emptyResults 为真,getResp() 也会运行。如何确保 getResp() 仅在 emptyResults 为 false 时运行?

我也尝试过编写如下 if 语句,但会引发错误 error: value map is not a member of Any

  acmResp <- if (!emptyResults) {
    getResp(content)
  }

我在这里查看了其他解决方案,包括 thisthisthis,但他们没有帮助解决这个问题。

【问题讨论】:

    标签: scala future for-comprehension


    【解决方案1】:

    for 理解是“语法糖”。这意味着在它被翻译成字节码之前,它首先被翻译成不同的、标准的语言结构。

    在这种情况下,您有一个生成器 &lt;- 和一个守卫 if ...。这将被转换为map() 调用和withFilter() 调用。所以,你看,你不能通过添加保护条件来阻止生成器执行。守卫只能充当传递给yield 的过滤器。

    要获得您想要的,您必须将条件测试移到 for 理解之外,此时将其变为简单的 map() 会更容易。

    val result = if (areResultsEmpty(content)) {
                    . . . //some default
                 } else {
                    getResp(content).map(/*do work*/)
                 }
    

    【讨论】:

      【解决方案2】:

      您可以在理解表达式中调用 areResultsEmpty 一个守卫。

      for {
        resp <- getResp(content) if !areResultsEmpty(content)
      } yield resp
      

      【讨论】:

        【解决方案3】:

        您不能在 for 理解中的任何生成器之前分配。

        for {
          emptyResults: Boolean = areResultsEmpty(content) // Not allowed
          resp <- getResp(content) if !emptyResults
        } yield resp
        

        尝试类似的方法:

        if(!areResultsEmpty(content)) {
          for {
              resp <- getResp(content)
          } yield resp
        }
        else {
          ...
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-07-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-17
          • 2015-01-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多