在 Scala 中使用 For Comprehension 仅在 If 测试后 flatMap Future[T]

Using For Comprehension in Scala to only flatMap Future[T] after an If Test

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

密码是

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

如果 emptyResults 为真,则 getResp() 会抛出错误,但在上面,即使 emptyResults 为真,getResp() 也会得到 运行。如果 emptyResults 为假,我如何确保 getResp() 仅得到 运行?

我也试过像下面这样写 if 语句,但是会抛出错误 error: value map is not a member of Any

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

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

您不能在 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 {
  ...
}

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

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

一个for理解是"syntactic sugar.",这意味着在它被翻译成字节码之前,它首先被翻译成一个不同的、标准的、语言结构。

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

的过滤器

为了得到你想要的东西,你必须将条件测试移到 for 理解之外,在这一点上,把它做成一个简单的 map().[=19 会更容易=]

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