对于理解和 Futures 类型不匹配

For comprehension and Futures is having a type mismatch

我收到类型不匹配错误,我似乎无法弄清楚原因。

found:        scala.concurrent.Future[UserSales]
required:     Option[UserSales]

       userSalesOpt <- getOrSetUserSales(userSalesCacheKey)

I have tried creating another for {} clause but that didn't solve the issue.  What should I be doing as I am stuck??

以下是我使用的方法:

UserDAO
  def getByUsername(name: String): Future[Option[User]]

UserController: 
  def getOrSetUserSales(key: String): Future[Option[UserSales]]

class UserController ... {

  def index = Action.asyc {
    val maybeUserSalesOpt: Future[Option[UserSales]] = for {
      userOpt <- userDao.getByUsername(name)
    } yield {
       for {
          user <- userOpt
          userSalesCacheKey = name + "whatever"
          userSalesOpt <- getOrSetUserSales(userSalesCacheKey)
       } yield {
         for {
           userSales <- userSalesOpt
         } yield userSales
       }
    }

    for {
      maybeUserSales <- maybeUserSalesOpt
    } yield {
      if(maybeUserSales.isDefined) {
        Ok("found")
      } else {
       Ok("error")
      }

    }

  }

}

类型不匹配来自for-comprehension的定义。结果类型需要与声明类型相同。

因此,如果您对 List 有 for-comprehension,您就会知道结果类型也是 List。

for(i <- List(Some(1), None, Some(2)); j <- i ) yield j
res: List[Int] = List(1, 2)

如果我尝试 return 不同的东西,编译器会抱怨:

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

for(i <- Future.apply(Option(2)); j <- i ) yield j
<console>:**: error: type mismatch;
 found   : Option[Int]
 required: scala.concurrent.Future[?]
              for(i <- Future.apply(Option(2)); j <- i ) yield j
                                                   ^

您正在尝试 return 一个选项,而 return 类型应该是一个 Future。


以下是在 Scala 中解决此类问题的方法(我抽象所有内容以便编译):

// Dummy types
type UserSales = String
type User = String

// Types of the main functions we have
type GetByUsername = String => Future[Option[User]]
type GetOrSetUserSales = String => Future[Option[UserSales]]

// Type of the function I want
type UserSaleGetter = (String, String) => Future[Option[UserSales]]

// A function that solves our problem (function combinator) 
def makeConditionalUserSalesGetter(userGetter: GetByUsername, 
                                   salesGetter: GetOrSetUserSales): UserSaleGetter = { 
   (userName: String, prodName: String) => 
      for(optUser <- userGetter(userName); p <- salesGetter(userName+prodName) )
          yield p
}

现在我们可以使用组合函数(类型为 UserSaleGetter)来提供用户和产品并取回 Future[Option[UserSales]]