解释在播放框架中传递请求

Explain request passing in play framework

我在 playframework 中尝试过这个。当我完成这一部分时,起初它看起来很简单,但在尝试追踪它时我无法理解它是如何工作的。我知道 Action 的 apply 方法接受什么样的参数,但我不知道请求是如何可用的以及如何将它传递给 Ok。任何人都可以在 scala 中显示具有简单定义的类似示例吗?

@Singleton
class HomeController @Inject()(configuration: Configuration, cc: ControllerComponents)(implicit assetsFinder: AssetsFinder)
  extends AbstractController(cc) {
  def tweets = Action { implicit request =>
    Ok(s"request is $request")
  }
}

提前致谢

对象Action extends trait DefaultActionBuilder extending trait ActionBuilder. The latter has method

apply(block: R[B] => Result): Action[B]

在你的情况下 requestRequest[AnyContent] 类型,即 RRequest 并且 BAnyContentOk(s"request is $request") 的类型是 Result,

Action { implicit request =>
  Ok(s"request is $request")
}

属于 Action[B] 类型,即 Action[AnyContent]。所以语法只是 apply 一个对象的方法和一个 lambda 作为方法的参数。

What is the apply function in Scala?

foo(implicit x => ???) 等同于 foo(x => { implicit val x_ = x; ??? }).

Implicit keyword before a parameter in anonymous function in Scala

Ok 就是 new Status(OK) i.e. new Status(200) and class Status has method

def apply[C](content: C)(implicit writeable: Writeable[C]): Result

C 现在是 Stringcontents"request is $request"(即字符串 "request is " + request.toString)。

如果您使用 IDE,您可以自己研究类似的继承层次结构和类型。

我会尝试简化一下:

trait A extends (String => String) { self => def apply() = this }

A 有效地将函数从 String 扩展到 String。

object A { def apply(f: String => String): A = new A { def apply(x: String) = f(x) } }

A 的伴随对象实际上实现了 A.

现在您可以这样做了:

val f: String => String = _.toLowerCase
A(f)

这是有效的 Scala 代码。

您定义 ftoLowerCase 在字符串上)并将其传递给 A 的 apply 方法。

也可以这样写:

A { s => s.toLowerCase } // this way of putting it should remind you of Action { request => ... }

这正是 Play ActionEssentialAction 的工作方式。

你问的另一件事是关于 Ok

Ok 被定义为 Status 的简短版本,具有设置的状态代码 (200) 和给定的正文(因此像 Ok("Hello world!") 这样的东西可以工作。

除此之外还有一些常见的 string interpolation 你应该知道。