Scala 如果用户存在,则返回该用户;否则,如果电子邮件地址选项存在,则插入
如果我有电子邮件,我想通过电子邮件获取用户(如果存在)。如果它不存在,我想插入并返回用户Scala 如果用户存在,则返回该用户;否则,如果电子邮件地址选项存在,则插入,scala,Scala,如果我有电子邮件,我想通过电子邮件获取用户(如果存在)。如果它不存在,我想插入并返回用户 val userOptFut: Future[Option[User] = emailOpt.map { email => userDao.getByEmail(email).map { maybeUserFut => maybeUserFut match { case Some(u) => Future.successful(Some(u)
val userOptFut: Future[Option[User] = emailOpt.map { email =>
userDao.getByEmail(email).map { maybeUserFut =>
maybeUserFut match {
case Some(u) => Future.successful(Some(u))
case None =>
userDao.insert(User(....)) // Future[User]
}
}
}.getOrElse(Future.successful(None))
其中userDao.getByEmail(..)
返回Future[Option[User]]
我不确定出了什么问题,但出于某种原因,它说我返回的是一个对象
,而不是用户
Future[Object]类型的表达式不符合预期类型
未来[选项[用户]]
上面的错误是什么?您的问题是
match
语句的两个分支返回的类型不同:
case Some(u) => u // User
case None => userDao.insert(User(....)) // Future[User]
根据您试图实现的目标,您可以执行以下操作:
case Some(u) => Future.successful(Some(u))
最后的
.getOrElse
可能也不适合您的类型。像这样的嵌套很难在任何地方正确匹配类型。编译器最终要做的是推断出它能推断出的最具体的类型,即对象
,而它与您声明的类型不匹配
它确实有助于将函数分解为更小的部分,嵌套级别更少,因此类型更难搞乱。我会这样做:
// This is very close to Future.sequence, but Option isn't a subclass
// of TraversableOnce. There's probably an existing function to do
// this in a library like cats or scalaz.
def toFutureOption[A](in: Option[Future[A]]): Future[Option[A]] = in match {
case Some(fut) => fut map {Some(_)}
case None => Future.successful(None)
}
def getOrInsert(email: String): Future[User] =
userDao.getByEmail(email) transformWith {
case Success(Some(user)) => Future.successful(user)
case Success(None) | Failure(_) => userDao.insert(User(email))
}
val userOptFut: Future[Option[User]] =
toFutureOption(emailOpt map getOrInsert)
getOrElse(无)
?因此,如果get失败,您将返回None
?这不符合类型Future[Option[User]]
(我怀疑如果get成功,它也不会符合)。@jwvh我用更新更新了我的Q,现在它说Future[Object],我认为现在的问题是无部分,因为它是Future[User],我需要Future[Option[User]]您应该在代码中添加一些变量,以确定要处理的类型。例如,为整个userDAO…
part分配一个val,并查看返回的类型getOrElse
应该在选项
类型上调用。