Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
885 views
in Technique[技术] by (71.8m points)

scala - Explicit return from play action

I have following action

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

  Ok("all ok")
}

This is giving me an Error. Intellij is suggesting Action[JsValue] type. When I say return will be of that type, I am getting again error on BadRequest line, because types doesn't match.

I tried searching about this problem, and I found some answers which are suggesting to set Action[AnyContent] as return type. But I am STILL getting error.

Also I need to return from if...I don't want to write else after that if, because in some more complex function most probably I will have few if statements which should break action, and if I use if/else approach, code will be nightmare.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You cannot use return in this context because the Scala compiler misinterprets what you mean by return. You intended for the return to return from the function that is being passed to Action.apply, i.e. this block:

{ request =>
  if (/* Let's we say here is some validation */) {
    return BadRequest("bad")
  }

  Ok("all ok")
}

However, in Scala return cannot be used to return from functions, only methods. Any return is interpreted as returning from the nearest enclosing method. In this case, the compiler thought you were returning from login.

You have the wrong type on login. login should be a Action[JsValue]. With that correct type, the compiler will complain about the return because you are returning a SimpleResult instead of the expected Action[JsValue]. With the incorrect type Result, the compiler accepts the return but then isn't happy because the return value of Action.apply is always a type of Action.

The reason return works this way is to support loops like:

def allPositive(l: List[Int]): Boolean = {
  l.foreach { x => if (x < 0) return false }
  true
}

But using return is unidiomatic. The return in the above loop is implemented with exception throwing so it is inefficient. And return can make for very confusing code:

def login: Result = Action(parse.json) { request =>
  /*
  WALL OF CODE WALL OF CODE WALL OF CODE WALL OF CODE WALL OF CODE
  WALL OF CODE WALL OF CODE WALL OF CODE WALL OF CODE WALL OF CODE
  WALL OF CODE WALL OF CODE WALL OF CODE WALL OF CODE WALL OF CODE
  WALL OF CODE WALL OF CODE WALL OF CODE WALL OF CODE WALL OF CODE
  WALL OF CODE WALL OF CODE WALL OF CODE WALL OF CODE WALL OF CODE
  WALL OF CODE WALL OF CODE WALL OF CODE WALL OF CODE WALL OF CODE
  WALL OF CODE WALL OF CODE WALL OF CODE WALL with return  OF CODE
  WALL OF CODE WALL OF CODE WALL OF CODE WALL OF CODE WALL OF CODE
  WALL OF CODE WALL OF CODE WALL OF CODE WALL OF CODE WALL OF CODE
  WALL OF CODE WALL OF CODE WALL OF CODE WALL OF CODE WALL OF CODE
  */

  Ok("all ok")
}

Obviously this login always returns Ok. Oh wait...there is a return buried in there.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...