final def apply(block: => Result): Action[AnyContent] =
apply(BodyParsers.utils.ignore(AnyContentAsEmpty: AnyContent))(_ => block)
Кто-нибуть знает что здесь означает AnyContentAsEmpty: AnyContent ? AnyContentAsEmpty я так понимаю это объект, который передается в BodyParsers.utils.ignore...? Даже не знаю как гуглить это AnyContentс двоеточием.
Ответ
Это называется ascription
Используется когда ты хочешь "поднять" тип до родительского. Пример аскрипции при инициализации:
// some имеет тип Some[Int]
val some = Some(43)
// some имеет тип Option[Int]
val some: Option[Int] = Some(43)
// вот тут аскрипция - и some имеет тип Option[Int]
val some = Some(43): Option[Int]
Ещё используют при вызове функции - как твоём примере. Дело в том, что функция ignore дженерик, т.е. её параметр типа А инициализируется типом из аргумента. От этого зависит тип который она вернёт.
BodyParsers.utils.ignore(AnyContentAsEmpty)
// res1: play.api.mvc.BodyParser[play.api.mvc.AnyContentAsEmpty.type]
BodyParsers.utils.ignore(AnyContentAsEmpty: AnyContent)
//res0: play.api.mvc.BodyParser[play.api.mvc.AnyContent]
Вот другой часто используемый пример -
вот так - НЕ скомпилируется
val list = List(1)
list.foldLeft(Right(0))( (accumulator, currentNum) => {
if (currentNum == 0) Left(new ArithmeticException)
else accumulator.right.map(_ + currentNum)
})
Из-за того что я передал Right(0) в первые скобки - то тип accumulator стал Right[Int], и вся функция ждёт Right[Int]
А если я "подниму" тип до Either с помощью аскрипции, то могу в функции возвращать и Right и Left
list.foldLeft(Right(0): Either[Exception, Int])( (accumulator, currentNum) => {
if (currentNum == 0) Left(new ArithmeticException)
else accumulator.right.map(_ + currentNum)
})
Ссылки:
дока,
стековерфлоу на английском.
Комментариев нет:
Отправить комментарий