简体   繁体   中英

Scala implement inline trait method

I've started learning scala and the play framework. I downloaded the sample project from the play framework site. I have a newbie question because I cannot understand the following syntax:

def count = Action { Ok(counter.nextCount().toString) }

What exactly does it do? Action is implemented function in BaseController, where action builder is assigned. What is the content the beetwen braces for? Wat do the braces mean in this context?

In playframework, requests are handled by Actions . When you invoke Action { ... } , you are actually invoking play.api.mvc.Action helper object to create Action values.

object Action extends ActionBuilder[Request] { ... } 

If you look closely to Action object, it extends to play.api.mvc.ActionBuilder trait. This trait contains various overloaded apply methods that creates Action values. Therefore, when you are invoking Action{ ... } you are actually invoking Action.apply({...}) and this apply method is inherited from ActionBuilder trait. If you look into ActionBuilder trait, you will see various higher ordered apply functions.

Now in your case, def count = Action { Ok(counter.nextCount().toString) }

You are actually invoking apply method with default content and no request parameter.

final def apply(block: => Result): Action[AnyContent] = apply(_ => block)

That means, you are providing block { Ok(counter.nextCount().toString) } which return Ok Result.

What is the content the beetwen braces for? Wat do the braces mean in this context?

When you do Action { Ok(counter.nextCount().toString) } , you are actually invoking:

Action.apply(Ok(counter.nextCount().toString))

In scala, apply method is a factory method and therefore you don't have to essentially call apply method, therefore you can also do Action(Ok(counter.nextCount().toString)) . Additionally, if your function takes only single parameter, you can replace () brackets with curly braces {} . ie you can do Action{Ok(counter.nextCount().toString)} .

I would suggest to look into function literals, higher ordered functions, by-name parameter, method currying etc. So, that you will have more insight in these.

The source code will give you the details:

/**
   * Constructs an `Action` with default content, and no request parameter.
   *
   * For example:
   * {{{
   * val hello = Action {
   *   Ok("Hello!")
   * }
   * }}}
   *
   * @param block the action code
   * @return an action
   */
  final def apply(block: => Result): Action[AnyContent] =
    apply(BodyParsers.utils.ignore(AnyContentAsEmpty: AnyContent))(_ => block)

It's equivalent to def count = Action.apply(Ok(counter.nextCount().toString))

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