Play Framework / Scala:行动中的“返回”声明?

时间:2015-02-10 19:41:44

标签: scala playframework

我知道这不是Scala写东西的方式。我想,在Scala中你会使用map。但是我想用这种方式编写它,因为它更像Java / c ++。 但是,编写以下代码时,Scala编译器会抱怨“方法addGroup具有return语句;需要结果类型”。 省略返回并使用else分支有效。但是出于结构化的原因,我想使用return,因为我不想缩进代码的其余部分,如果你使用“else {}”就会发生这种情况。

添加结果类型的位置。并且“未来[结果]”是正确的类型吗?

def addGroup = Action { implicit request =>
  val optionUser = GetUserFromSession(request)
  if (optionUser == None) {
    return Redirect(routes.ApplicationUser.show(0))
  }
  Redirect(routes.ApplicationUser.show(optionUser.get.id))
}

1 个答案:

答案 0 :(得分:6)

你做不到。 Action.apply的主体是一个匿名函数,你试图过早地从中返回。问题是,Scala中的return关键字从最内层的命名的方法返回,而这肯定不是。因此,您将尝试返回Result,其中方法需要Action[A]

唯一可行的方法是拆分功能:

def addGroup = Action { implicit request =>
  result(request)
}

// Could have a better name, but whatever, you shouldn't do this.
def result(request: Request): Result = {
  val optionUser = GetUserFromSession(request)
  if (optionUser == None) {
    return Redirect(routes.ApplicationUser.show(0))
  }
  Redirect(routes.ApplicationUser.show(optionUser.get.id))
}

使用return会使代码变得奇怪且难以阅读,所以请不要这样做。

如果真的需要保存单个缩进,那么这个呢?

def addGroup = Action { implicit request =>
  val optionUser = GetUserFromSession(request)
  if (optionUser == None) Redirect(routes.ApplicationUser.show(0))
  else Redirect(routes.ApplicationUser.show(optionUser.get.id))
}

就个人而言,我会使用mapgetOrElse

重写此内容
def addGroup = Action { implicit request =>
  GetUserFromSession(request) map { user =>
     Redirect(routes.ApplicationUser.show(user.id))
  } getOrElse {
     Redirect(routes.ApplicationUser.show(0))
  }     
}

它不需要使用.get,也可以优先考虑正分支。