Scala 游戏动作的显式返回

Scala 游戏动作的显式返回,scala,playframework,Scala,Playframework,我有以下行动 def login: Result = Action(parse.json) { request => if (/* Let's we say here is some validation */) { return BadRequest("bad") } Ok("all ok") } 这给了我一个错误。Intellij建议Action[JsValue]type。当我说return将是那种类型时,我在BadRequest行上再次遇到错误,因为类型不匹配

我有以下行动

def login: Result = Action(parse.json) { request =>
  if (/* Let's we say here is some validation */) {
    return BadRequest("bad")
  }

  Ok("all ok")
}
这给了我一个错误。Intellij建议
Action[JsValue]
type。当我说return将是那种类型时,我在
BadRequest
行上再次遇到错误,因为类型不匹配

我试着搜索这个问题,找到了一些答案,建议将
Action[AnyContent]
设置为返回类型。但我还是有错误


另外,我需要从
if
返回…我不想在
if
之后再写
else
,因为在一些更复杂的函数中,我很可能会有一些
if
语句,这些语句应该会中断操作,如果我使用
if/else
方法,代码将是噩梦。

当然。在Scala中,嵌套匿名函数中的“return”语句是通过抛出和捕获非LocalReturnException来实现的。它在第6.20节中这样说

这样做是因为为了理解,为了让人们能够编写这样的代码:

def loop() = {
  for (i <- 0 until 20) {
    if (someCondition) return
  }
}
你能看到匿名函数吗?你能看到问题中的“return”并不是指仅从匿名函数返回吗?在我看来,这是一个设计错误。另一方面,在Scala这样的语言中,无论如何都不需要“return”

这里有一个匿名函数:

Action(parse.json) { request => ... this one here ... }
在这个函数中,您使用的是“return”,它在引擎盖下触发了一个异常

所以Scala的一般经验法则是永远不要使用RETURN。无论如何,它是一种面向表达式的语言。你不需要它

Action(parse.json) { request =>
  if (/* Let's we say here is some validation */) 
    BadRequest("bad")
  else
    Ok("all ok")
}
在这里,更地道。顺便说一句,你也没有“中断”或“继续”。习惯在没有他们的情况下工作。另外,关于您的意见:

此外,我还需要从if返回…我不想在if之后再编写其他if,因为在一些更复杂的函数中,最有可能的是,我会有一些if语句,它们会破坏操作,如果我使用if/else方法,代码将是噩梦

这是错误的,我真的很讨厌使用依赖于返回、中断或继续来短路逻辑的代码,因为复杂的逻辑变得混乱,我想清楚地了解:

  • 不变量,如果我们谈论循环的话
  • 退出条件
  • 分支/路径
  • 使用return、break或continue会破坏所有3点的清晰度。它们并不比跳转好多少。如果你有复杂的函数,如果阅读它开始成为一个问题,把它们分成多个函数


    此外,比多个“if/else”分支更好的是“match”语句。一旦你习惯了它们,你就会爱上它们,特别是考虑到编译器甚至可以在你缺少一个分支的情况下保护你。

    当然可以。在Scala中,嵌套匿名函数中的“return”语句是通过抛出和捕获非LocalReturnException来实现的。它在第6.20节中这样说

    这样做是因为为了理解,为了让人们能够编写这样的代码:

    def loop() = {
      for (i <- 0 until 20) {
        if (someCondition) return
      }
    }
    
    你能看到匿名函数吗?你能看到问题中的“return”并不是指仅从匿名函数返回吗?在我看来,这是一个设计错误。另一方面,在Scala这样的语言中,无论如何都不需要“return”

    这里有一个匿名函数:

    Action(parse.json) { request => ... this one here ... }
    
    在这个函数中,您使用的是“return”,它在引擎盖下触发了一个异常

    所以Scala的一般经验法则是永远不要使用RETURN。无论如何,它是一种面向表达式的语言。你不需要它

    Action(parse.json) { request =>
      if (/* Let's we say here is some validation */) 
        BadRequest("bad")
      else
        Ok("all ok")
    }
    
    在这里,更地道。顺便说一句,你也没有“中断”或“继续”。习惯在没有他们的情况下工作。另外,关于您的意见:

    此外,我还需要从if返回…我不想在if之后再编写其他if,因为在一些更复杂的函数中,最有可能的是,我会有一些if语句,它们会破坏操作,如果我使用if/else方法,代码将是噩梦

    这是错误的,我真的很讨厌使用依赖于返回、中断或继续来短路逻辑的代码,因为复杂的逻辑变得混乱,我想清楚地了解:

  • 不变量,如果我们谈论循环的话
  • 退出条件
  • 分支/路径
  • 使用return、break或continue会破坏所有3点的清晰度。它们并不比跳转好多少。如果你有复杂的函数,如果阅读它开始成为一个问题,把它们分成多个函数


    此外,比多个“if/else”分支更好的是“match”语句。一旦你习惯了它们,你就会爱上它们,特别是考虑到编译器甚至可以在你缺少分支的情况下保护你。

    在这种情况下你不能使用
    return
    ,因为Scala编译器误解了你所说的
    return
    的意思。您希望
    返回
    从传递给
    操作的函数返回。应用
    ,即此块:

    { request =>
      if (/* Let's we say here is some validation */) {
        return BadRequest("bad")
      }
    
      Ok("all ok")
    }
    
    但是,在Scala中,不能使用
    return
    从函数返回
    return
    ,只能使用方法。任何
    返回
    都被解释为从最近的封闭方法返回。在本例中,编译器认为您是从
    登录返回的

    您在
    登录
    上的类型错误<代码>登录
    应该是一个
    操作[JsValue]
    。使用正确的类型,编译器将抱怨返回,因为您返回的是
    SimpleResult
    ,而不是预期的
    Action[JsValue]
    。对于不正确的类型
    结果
    ,编译器接受
    返回
    ,但随后不高兴,因为
    操作的返回值。应用
    始终是
    操作
    的一种类型

    return
    以这种方式工作的原因是支持如下循环:

    def allPositive(l: List[Int]): Boolean = {
      l.foreach { x => if (x < 0) return false }
      true
    }
    
    显然,这个
    登录总是返回
    Ok
    。哦,等等……有一个