0

我正在尝试使用 Play2 和 reactivemongo 在 mongodb 中找到可用的 slug。我想出了以下递归方法。

  private def findSlug(base: String, index: Int): String = {
    val slug: String = Slug({
      base + "-" + index
    })
    for {
      user <- findOne(BSONDocument("slug" -> slug))
    } yield {
      user match {
        case None => slug
        case Some(user) => findSlug(base, index+1)

      }
    }
  }

我收到以下错误

found   : scala.concurrent.Future[String]
required: String
        user <- findOne(BSONDocument("slug" -> slug))
             ^

我在更改返回类型、映射收益结果等方面玩了很多,但不知何故,我认为可能有一个更简单、简洁和正确的解决方案。这一切都归结为有一个递归函数,它调用我认为的另一个异步函数。

如果我将 findSlug 的返回类型更改为 Future[String] 我得到

[error]  found   : scala.concurrent.Future[String]
[error]  required: String
[error]         case Some(user) => findSlug(base, index+1)
[error]                                    ^

什么是正确和惯用的解决方案?

4

1 回答 1

1

我个人认为将返回类型设置为 aFuture[String]是正确的方法——这意味着你可以尽可能长时间地保持整个“反应性”、单子、未来链的事情(对于 Play 2,这可以是一直到控制器级别 - 太棒了)。

我假设您的findOne()方法只是一些 Reactive Mongo 查询的包装器,它会Future[Option[T]]在某个时候返回 a?

考虑到这一点,唯一真正的问题是Future来自您的两个不同case的 s 的 y-ness 水平不同。

这就是我想出的。有用; 它是惯用的吗?你告诉我 ...

private def findSlug(base: String, index: Int): Future[String] = {

  // Slug stuff omitted

  findOne(BSONDocument("slug" -> slug)).flatMap { _ match {
      case None => Future.successful(slug)
      case Some(_) => findSlug(base, index+1)
    } 
  }
}
于 2013-11-15T13:12:38.213 回答