Закрытие с типизированными аргументами в 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.