В Scala функция действительно определяется с использованием черты, например,
object foo extends (Int => String) {
def apply(i: Int): String = s"hello $i"
}
или
val foo: Int => String = i => s"hello $i"
или
val foo = new Function1[Int, String] {
override def apply(i: Int): String = s"hello $i"
}
все определяют функциюмы можем позвонить с помощью foo(42)
, что приводит к foo.apply(42)
.
Действие
trait Action[A] extends EssentialAction
, где EssentialAction
равно
trait EssentialAction extends (RequestHeader) => Accumulator[...]
где мы видим синтаксис extends (RequestHeader) => Accumulator
.Обратите внимание, что A => B
является синтаксическим сахаром для признака Function1
, поэтому мы можем написать
trait EssentialAction extends Function1[RequestHeader, Accumulator[...]]`
Теперь черта Action
также имеет объект-компаньон Action
, который принимает аргумент функции block
и создает Action
с телом запроса по умолчанию:
Action.apply(block: (Request[AnyContent]) => Result): Action[AnyContent]
, и это фактически то, что используется, когда мы пишем
Action { request =>
Ok("Got request [" + request + "]")
}