简体   繁体   中英

Scala method = trait { … } meaning

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 ;))

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

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 ).

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM