Groovy: можно построить карту функций? - PullRequest
0 голосов
/ 03 сентября 2018

У меня есть список элементов, и я хочу построить карту, которая для каждого элемента в этом списке содержит вызов метода. Например:

list = ['a', 'b', 'c']
map = list.collectEntries{[it: println(it)]}
map[b]

>>b

Это не работает из-за двух проблем:

  1. println сразу же выполняется при назначении ключа на карте
  2. map[b] встречается с ошибкой: groovy.lang.MissingPropertyException: No such property: b for class: test

Можно ли создать такую ​​карту без немедленного выполнения команд? Как это можно сделать?

ПРИМЕЧАНИЕ. Я знаю, что то, чего я хочу достичь, звучит немного странно, но мне дали метод, который принимает такую ​​карту в качестве аргумента, а затем запускает команды, поэтому у меня нет другой опции, такой как for-loop и прочее

1 Ответ

0 голосов
/ 03 сентября 2018

Если вы хотите хранить функции на карте и лениво их оценивать, вам, например, придется хранить эти функции как замыкания. Рассмотрим следующий пример:

def list = ['a', 'b', 'c']
def map = list.collectEntries { el -> [(el): { println el }] }
map.b()

В этом случае функция оценивается только тогда, когда она выполняется, и теперь, когда ей назначается ключ карты. Также вам придется использовать явный параметр имени, такой как el, потому что если вы полагаетесь на it, он меняет контекст при доступе к закрытию.

Существует несколько способов выполнения функции, хранящейся на карте. Рассмотрим следующие выражения в качестве примера:

map.b()
map.b.call()
map['b']()
map['b'].call()
map.getAt('b').call()

Если вы хотите сделать выполнение функции NPE безопасным, то лучшим вариантом будет следующее выражение:

map.getAt('b')?.call()

В этом случае звоните

map.getAt('d')?.call()

не сгенерирует никаких исключений.

...