Scala method = trait { … } meaning

痴心易碎 提交于 2020-01-03 16:57:11

问题


I'm trying to learn Scala and the Play Framework at the same time. Scala looks to me like it has a lot of really cool ideas, but one of my frustrations is trying to understand all of the different syntaxes for methods/functions/lambdas/anonymous functions/etc.

So I have my main application controller like so:

object Application extends Controller {
  def index = Action {
    Ok(views.html.index("Your new application is ready."))
  }
}

This tells me I have a singleton Application that has one method, index, that returns what type?? I was expecting index to have a definition more like:

def index(req: Request) : Result = { ... }

Looking at Play Framework's documentation, it looks as though Action is a trait, that transforms a request to a result, by I'm having a hard time understanding what this line is saying:

def index = Action { ... }

I come from a Java background, so I don't know what this is saying? (this statement feels like it's saying "method index = [some interface Action]", which doesn't make sense to me; it seems something beautiful is happening, but it is magic to me, and I feel uneasy with magic in my code ;))


回答1:


When you invoke an object as if it were a function, that's translated into a call to apply. I.e.:

foo(bar)

is translated into

foo.apply(bar)

So, inside index you are calling the Action object as if it were a function, which means you are actually calling Action.apply.

The return type of index is omitted because the compiler can infer it to be the return type of Action.apply (which I guess from the name is Unit).




回答2:


So the short answer to this question is that there's some stuff going on behind the scenes that makes the above work: namely that the compiler is inferring types, and in Scala, objects with an apply method can get called as if they were functions.

So what's going on here is that this code:

def index = Action {
  Ok("Hello World!")
}

...is equivalent to (or rather shorthand for) this code:

def index : Action[AnyContent] = Action.apply(
    (req: Request[AnyContent]) => {
        Ok(views.html.index("Hello World!"))
    } : Result
)

The magic is happening here: ... = Action {...}. Action {...} says "call Action with this anonymous function {...}".

Because Action.apply is defined as apply(block: => Result): Action[AnyContent], all of the argument-/return- types can be inferred.



来源:https://stackoverflow.com/questions/19963318/scala-method-trait-meaning

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!