关于Play框架代码的困惑

时间:2014-12-27 05:31:07

标签: scala playframework

我是斯卡拉地区的新手,最近,我正在尝试玩Play框架。我用Play控制台生成了我的第一个应用程序。

之后,我正在阅读代码,但对于以下代码片段,我感到很困惑。

package controllers

import play.api._
import play.api.mvc._

object Application extends Controller {

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

就文档而言,Action是一个伴随对象,但是大括号后面的伴随对象的语法是什么,就像Java中的接口的匿名实现,或者大括号内的内容是apply的覆盖方法

请指教,非常感谢。对于斯卡拉退伍军人这个天真而简单的问题,我们深表歉意。

2 个答案:

答案 0 :(得分:2)

行动是延伸EssentialAction的特质

trait Action[A] extends EssentialAction

Essential Action只是一个函数。给一个RequestHeader,一个EssentialAction使用请求体(一个数组[Byte])并返回一个Result。

trait EssentialAction extends (RequestHeader) ⇒ Iteratee[Array[Byte], Result] with Handler

ActionBuilder是一个辅助特征,它具有构造Action的方法。这个特性包含多个重载的异步和应用方法。如果要定义自定义操作(或)将一个操作组合到另一个(或)执行一个操作,则必须使用此特征并构建自己的操作。

trait ActionBuilder[+R[_]] extends ActionFunction[Request, R]

但是Action {...}的语法是什么。特征ActionBuilder有一个伴随对象,它也具有相同的名称Action。请注意,这与列车行动[A]不同。该对象重写InvokeBlock方法。在scala中,您也可以定义对象。您定义一个对象并提供一个apply方法,该方法在您调用该对象时被调用。

object Action extends ActionBuilder[Request] {companion
  def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]) = block(request)
}

你在大括号中传递的内容{...}只不过是在invokeBlock中定义为参数的块。在scala中,你可以使用parantheses或braces将参数传递给函数,当你有像block这样的多行表达式时,大括号可以很好地工作。这个invokeBlock方法是从ActionBuilder trait中的apply的重载版本调用的。

据我所知,对于支撑内部的东西来说,这有点令人难以理解,感觉很容易,我花了大约10天的时间来弄明白这一点。欢迎来到Scala !!!

来源:

  1. 源代码 - https://github.com/playframework/playframework/blob/2.3.x/framework/src/play/src/main/scala/play/api/mvc/Action.scala

  2. 稀疏文档 - https://www.playframework.com/documentation/2.3.x/ScalaActionsComposition

  3. 播放api文档 - https://www.playframework.com/documentation/2.3.x/api/scala/index.html#play.api.mvc.ActionBuilder

  4. 关于行动组合的优秀博客 - http://www.mariussoutier.com/blog/2013/09/17/playframework-2-2-action-building-action-composition/

答案 1 :(得分:1)

这是Action.apply的语法糖。 (您无法匿名实施object,但如果这是trait,则可能需要new)。它有一些重载:

final def apply[A](bodyParser: BodyParser[A])(block: R[A] => Result): Action[A]

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

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

您的代码段正在使用这三个中的最后一个。顺便说一句,它们都返回实现Action[A]特征的对象。