Scala Код demystify
Может ли кто-то демистифицировать этот код, который является частью примера zentasks в структуре Play20. Мне любопытно, как это работает, если я новичок в Scala с Java, поэтому многие вещи трудно оборачивать вокруг.
def IsAuthenticated(f: => String => Request[AnyContent] => Result) =
Security.Authenticated(username, onUnauthorized) { user =>
Action(request => f(user)(request))
}
Ответы
Ответ 1
Вам нужно немного разбить подпись. f
- это функция, которая принимает еще не вычисленную строку => String
и возвращает другую функцию, которая принимает Request[AnyContent]
и возвращает результат.
Вызов Security.Authenticated
принимает два списка параметров. Тот, у которого есть username
и onUnauthorized
. Вторая принимает функцию, принимающую пользователя и возвращающую действие.
Метод Action.apply
принимает функцию Request[AnyContent] => Result
поэтому f вызывается в "curried". Это называется первая функция, а затем полученная функция сразу используется f(user)(request)
.
Здесь то же самое, что и было (по крайней мере, как можно лучше) и уродливо:
def isAuthenticated(f: => String => Request[AnyContent] => Result) =
Security.Authenticated(username, onUnauthorized) { user: String =>
Action.apply { request: Request[AnyContent] =>
val hiddenTmp: Request[AnyContent] => Result = f(user)
hiddenTemp.apply(request)
}
}
Вы можете видеть, что компилятор выполняет небольшую работу, удаляя аннотации типов. Надеюсь, что это поможет объяснить, как он desugars в raw scala. По сути, функция выполняет много функциональной композиции.
Ответ 2
Прежде всего от руководства пользователя к моему ответу: я буду использовать курсив, чтобы указать функцию, которая используется без явного имени (см. анонимные функции).
IsAuthenticated - это метод, который принимает в качестве параметра аргумент f.
f - это функция, которая принимает Y как параметр и создает экземпляр Result
Y - это функция, которая принимает Z как параметр и создает экземпляр Request [AnyContent]
Z - это функция, которая не принимает параметров и возвращает строку
IsAuthenticated calls Security.Authenticated, передача имени пользователя и onUnauthorized (функция для вызова, когда пользователь не уполномочен выполнять запрошенное действие).
Я не совсем уверен, что происходит здесь уже здесь. Я не совсем хорошо знаком с Scala, но мое предположение заключается в том, что Security.Authenticated - это класс case, а следующее эквивалентно подклассификации и добавлению конструктора в java:
{
Action(request => f(user)(request))
}
Если эта часть моего предположения верна, тогда вызывается Action (являющийся методом Security.Authenticated), передавая в качестве аргумента A.
A - это функция, которая берет объект Request (я предполагаю это имя класса) и производит результат. Использование результата подразумевается здесь, потому что реализация A является вызовом функции f.
Итак, когда подкласс Security.Authenticated инициируется, вызывается действие, которое аутентифицирует пользователя для какого-либо действия (задается как String), а затем, если пользователь аутентифицирован, возвращает f (исходный параметр), который предположительно называется по действию (после вышеупомянутой проверки подлинности). Этот вызов f возвращает результат, который также является функцией. Затем результат окончательно вызывается с запросом (который был передан A) в качестве параметра.