Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如果用户存在,则返回该用户;否则,如果电子邮件地址选项存在,则插入_Scala - Fatal编程技术网

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
应该在
选项
类型上调用。