我是斯卡拉地区的新手,最近,我正在尝试玩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的覆盖方法
请指教,非常感谢。对于斯卡拉退伍军人这个天真而简单的问题,我们深表歉意。
答案 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 !!!
来源:
稀疏文档 - https://www.playframework.com/documentation/2.3.x/ScalaActionsComposition
播放api文档 - https://www.playframework.com/documentation/2.3.x/api/scala/index.html#play.api.mvc.ActionBuilder
关于行动组合的优秀博客 - 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]
特征的对象。