Закрытие с типизированными аргументами в Groovy - PullRequest
12 голосов
/ 15 апреля 2011

Я бы хотел быть более откровенным в отношении своих замыканий относительно их типов аргументов.Поэтому я написал бы что-то вроде

List<Y> myCollect(List<X> list, Closure<X,Y> clos) { ... }

Я знаю, что Groovy не будет использовать эту информацию о типах, но Groovy ++ может использовать ее во время компиляции.Может ли это быть достигнуто (кроме размещения в комментариях)?

ОБНОВЛЕНИЕ: Название может показаться вводящим в заблуждение, но я подумал, что приведенный выше пример сделает его более понятным.Я заинтересован в указании типов замыкания, которое является аргументом некоторой функции.Предположим, я хочу переопределить встроенный collect.Поэтому я заинтересован в написании myCollect, а не в написании clos.Чего я хочу добиться, так это получить ошибки времени компиляции

myCollect(['a', 'ab'], { it / 2 }) // compile error
myCollect(['a', 'ab'], { it.size() })  // OK 

Ответы [ 2 ]

8 голосов
/ 18 апреля 2011

Вы можете определить типы параметров замыкания, но приведенный выше синтаксис неверен. Вот закрытие без типов параметров:

def concatenate = {arg1, arg2 ->
  return arg1 + arg2
}

А вот такое же замыкание с типами параметров

def concatenate = {String arg1, String arg2 ->
  return arg1 + arg2
}

Я знаю, что Groovy не будет использовать эту информацию о типах, но Groovy ++ может использовать ее во время компиляции.

Groovy выполняет некоторую проверку типов во время компиляции, но не так сильно, как Groovy ++ (или Java). Даже если информация о типе не используется во время компиляции, она будет проверена во время выполнения, а также полезна в качестве формы документации.

2 голосов
/ 27 мая 2014

Полагаю, вы больше не используете 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.

...