Закрытие с типизированными аргументами в Groovy
Я хотел бы быть более явным о моих закрытиях относительно их типов аргументов. Поэтому я бы написал что-то вроде
List<Y> myCollect(List<X> list, Closure<X,Y> clos) { ... }
Я знаю, что Groovy не будет использовать эту информацию типа, но Groovy++ может использовать ее во время компиляции. Можно ли этого достичь (кроме как поместить его в комментарий)?
обновление:
Название может показаться вводящим в заблуждение, но я думал, что приведенный выше пример сделает его более ясным. Меня интересует указание типов закрытия, которое является аргументом некоторая функция. Предположим, я хочу redefince встроенный collect
. Поэтому мне интересно писать myCollect
, а не в письменной форме clos
. То, что я хочу достичь, это получить ошибки времени компиляции
myCollect(['a', 'ab'], { it / 2 }) // compile error
myCollect(['a', 'ab'], { it.size() }) // OK
2 ответов
Вы можете определить типы параметров закрытия, но синтаксис, показанный выше, является неправильным. Вот закрытие без типов параметров:
def concatenate = {arg1, arg2 ->
return arg1 + arg2
}
и вот такое же закрытие с типами параметров
def concatenate = {String arg1, String arg2 ->
return arg1 + arg2
}
Я знаю, что Groovy не будет использовать эту информацию типа, но Groovy++ может использовать ее во время компиляции.
Groovy выполняет некоторую проверку типов во время компиляции, но не столько, сколько Groovy++ (или Java). Даже если информация о типе не используется во время компиляции он будет проверяться во время выполнения, а также ценен как форма документации.
Я предполагаю, что вы больше не используете Groovy++, но даже если вы это можете работать. Он, безусловно, работает для статически типизированного Groovy 2.x
interface Z {
void callback(X x, Y y)
}
List<Y> myCollect(List<X> list, Z clos) {
...
clos.callback(x, y)
}
вызывающий затем вызывает его с нормальным:
List<Y> object.myConnect(list) { X x, Y y ->
}
Если вы оставляете параметр и имеете @CompileStatic, компилятор подбирает отсутствующие параметры или плохие типы.
это работает, потому что интерфейс метода 1 эквивалентен закрытию в Groovy.