将未来[对象]转换为未来[S]

时间:2018-04-09 23:54:18

标签: scala

我正在努力创作期权和期货。我有一个方法find,它返回一个Future[Option[User]],我正在编写另一个调用它的函数,执行一些操作,然后应该返回另一个Future[Option[User]]。问题是我无法正确签名。以下是方法:

def find(userID: BSONObjectID): Future[Option[User]]
def save(user: User): Future[User]

我想写的东西:

def saveToken(token: String, id: BSONObjectID) = {
  userDAO.find(id).map {
    case Some(user) =>
      userDAO.save(user.copy(newToken = Some(token))).map(u => Some(u))
    case _ => None
  }
}

我想我几乎拥有它。问题是签名目前是Future[Object],但我需要Future[Option[User]]。我的想法是,只有在找到用户时才想在我的持久层中向用户添加token字段。如果用户不存在(由User标识),我希望该方法返回Noneid

1 个答案:

答案 0 :(得分:3)

问题在于case _,它返回的Optioncase Some(user)返回的内容不匹配。要匹配其返回类型,请使默认大小写返回Future.successful(None),如以下虚拟示例所示:

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

case class User(name: String, newToken: Option[String])

val u1 = User("david", Some("t1"))
val u2 = User("rachel", Some("t2"))

List(Some(u1), Some(u2), None).map{
  case Some(user) => Future{ user.copy(newToken = Some("ok")) }.map(Some(_))
  case _ => None
}
// res1: List[Object] = List(Future(<not completed>), Future(<not completed>), None)

List(Some(u1), Some(u2), None).map{
  case Some(user) => Future{ user.copy(newToken = Some("ok")) }.map(Some(_))
  case _ => Future.successful(None)
}
// res2: List[scala.concurrent.Future[Option[User]]] = List(
//   Future(<not completed>), Future(<not completed>), Future(Success(None))
// )