了解 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]
我正在努力学习 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]