了解 Scala 函数的语法

Understanding syntax of a scala function

我正在努力学习 Scala。我知道如何编写函数。这就是我写函数的方式。

def test_function: Unit = {
    println("This is just a test")
}

但后来我开始学习 playframework。这就是他们在游戏中的控制器中编写函数的方式。

def test_function: Unit = Action{
    println("This is just a test")
}

我的问题是这个 Action 在花括号之前做什么?这叫什么?我怎样才能写我自己的?我希望我已经把我的问题说清楚了。提前致谢。

您可以通过在名为 Action:

object 上定义一个 apply 方法来获得这种行为
object Action { 
  def apply(block: => Unit): Unit = {
    println("before")
    block                 // do the action in the block
    println("after") 
  }
}

那么这两个:

Action { println("hi") }
Action(println("hi"))

制作这个:

before
hi
after

Action 后大括号中的内容只是 apply 方法的参数。 Scala 允许括号或大括号,但使用大括号允许您将多个语句放入:

Action {
  println("a")
  println("b")
}

产量:

before
a
b
after

Action 基本上是形状 play.api.mvc.Request => play.api.mvc.Result 的函数别名。当您看到 Action { } 时,您实际上看到的是该类型的伴随对象的 apply 函数,并且正在传递一个应该提供该 Request => Result 函数的主体。

伴生对象的形状大致为:

object Action {
  def apply(f: Request => Response): Action = ...
}

这样当您调用 Action { ... } 时,{ ... } 就是将在调用操作时执行的函数。

在您的示例中,println("This is just a test") 充当 Result 的提供者。

Action 是一个特征 (play.api.mvc.Action)。本质上它代表了这种类型:play.api.mvc.Request => play.api.mvc.Result (doc1, doc2).

在您的情况下,您使用的是 Action {...},它等效于 Action(...) 并由编译器转换为 Action.apply(...) 调用。如果您检查 source code,您会看到 apply 方法签名不仅在 Action 特征及其伴生对象上定义,而且在此处:

/**
 * Provides helpers for creating `Action` values.
 */
trait ActionBuilder[+R[_]] extends ActionFunction[Request, R]

在你的情况下,你没有接受任何请求,也没有产生任何响应,所以基本上你的 Action 是一个形式为 apply(block: => Result) 的函数调用,其中 Result 被丢弃,因为您将函数的 return 类型定义为 Unit.

Action 支持多种处理其主体的方法(包括 Futures),因此请选择正确的 apply 方法来满足您的需求。

如果需要,您可以扩展 Action,因为它不是最终实现。 Here 是一个例子:

case class Logging[A](action: Action[A]) extends Action[A]