Scala 未来如何解包选项?

Scala 未来如何解包选项?,scala,Scala,我想实现一个方法,如果用户还不存在,它将创建一个用户。如果确实存在,则应返回用户 这是我的密码: def createUserIfNotExists(user: User) = { for { count <- userService.count(Some(user)) user <- if (count == 0) createUser(user) else userService.findOneByName(user.name) } yield user } def c

我想实现一个方法,如果用户还不存在,它将创建一个用户。如果确实存在,则应返回用户

这是我的密码:

def createUserIfNotExists(user: User) = {
for {
  count <- userService.count(Some(user))
  user <- if (count == 0) createUser(user) else userService.findOneByName(user.name)
} yield user
}
def createUserIfNotExists(用户:用户)={
为了{

countJust
map
createUser
函数返回类型:

if (count == 0) createUser(user).map(Option(_)) else userService.findOneByName(user.name)

findOneByName
的返回类型包含一个
选项这一事实表明您可能没有用户。该类型的存在是有原因的,因此丢弃它是不好的,因为它会丢弃信息。
map
函数返回类型:

if (count == 0) createUser(user).map(Option(_)) else userService.findOneByName(user.name)

findOneByName
的返回类型包含一个
选项这一事实表明您可能没有用户。该类型的存在是有原因的,所以丢弃它是不好的,因为它会丢弃信息。

make
createUser
也会返回
Future[Option[\u]

def createUserIfNotExists(user: User) = {
  for {
   count <- userService.count(Some(user))
   userOpt <- if (count == 0) createUser(user).map(Some(_)) else userService.findOneByName(user.name)
  } yield userOpt
}

如果不创建用户,请首先尝试检索用户

def createUserIfNotExists(user: User) = {
 for {
   userOpt <- userService.findOneByName(user.name)
   user <-  userOpt match {
      case Some(value) => value
      case None => createUser(user).map(_ => user)
   }
 } yield user
}
def createUserIfNotExists(用户:用户)={
为了{
userOpt createUser(user).map(=>user)
}
}屈服用户
}

请注意,为确保并行数据库操作的正确性,强烈建议在
事务中执行上述代码

make
createUser
还返回
Future[Option[\u]]

def createUserIfNotExists(user: User) = {
  for {
   count <- userService.count(Some(user))
   userOpt <- if (count == 0) createUser(user).map(Some(_)) else userService.findOneByName(user.name)
  } yield userOpt
}

如果不创建用户,请首先尝试检索用户

def createUserIfNotExists(user: User) = {
 for {
   userOpt <- userService.findOneByName(user.name)
   user <-  userOpt match {
      case Some(value) => value
      case None => createUser(user).map(_ => user)
   }
 } yield user
}
def createUserIfNotExists(用户:用户)={
为了{
userOpt createUser(user).map(=>user)
}
}屈服用户
}

请注意,为确保并行数据库操作的正确性,强烈建议在
事务中执行上述代码,直接使用
findOneByName
函数,这样就不必查询数据库两次:

val res: Future[UserDB] = 
  userService
    .findOneByName(user.name)
    // if the option in the future is not empty, return its content
    // otherwise create a new user
    .flatMap(_.map(Future.successful).getOrElse(createUser(user)))

直接使用
findOneByName
函数,这样就不必查询数据库两次:

val res: Future[UserDB] = 
  userService
    .findOneByName(user.name)
    // if the option in the future is not empty, return its content
    // otherwise create a new user
    .flatMap(_.map(Future.successful).getOrElse(createUser(user)))

理解的
没有任何作用。@jwvh为什么?您能解释一下吗?因此,注释不允许我显示格式化代码,但CNTL复制以下内容并插入空格以进行尝试:
def createUserIfNotExists(用户:用户)=if(userService.count(Some(用户))>0)userService.findOneByName(user.name)else createUser(用户)
@jwvh我理解的原因是为了解决未来。啊,我的错。我不清楚
count()?您能解释一下吗?因此,注释不允许我显示格式化代码,但CNTL复制以下内容并插入空格以进行尝试:
def createUserIfNotExists(用户:用户)=if(userService.count(Some(用户))>0)userService.findOneByName(user.name)else createUser(用户)
@jwvh我理解的原因是为了解决未来。啊,我的错。我不清楚
count()
是否也会返回
Future
。您的第三个答案不会编译。你在用一种混合的方式来理解。@wheaties。。编辑了答案。。请检查。。。我没有;不要担心类型,因为问题中并没有给出完整的代码,编译器留给用户。我有兴趣给出主要想法(仅解决方案的关键点),您的第三个答案不会编译。你在用一种混合的方式来理解。@wheaties。。编辑了答案。。请检查。。。我没有;不要担心类型,因为问题中并没有给出完整的代码,编译器留给用户。我对给出主要想法感兴趣(仅解决方案的关键)