Я думаю, что сохранение переданных функций collect
или findAll
свободными от побочных эффектов - это хорошая идея в целом, не только для того, чтобы сохранить низкую сложность, но и для того, чтобы сделать код более дружественным к параллельным в случае, если параллельное выполнение необходимо вбудущее.
Но в случае each
нет особого смысла сохранять побочный эффект функции свободным, так как он ничего не сделает (фактически единственная цель этого метода - заменить действиекак для каждого цикла).Документация Groovy содержит несколько примеров использования each
(и его вариантов eachWithIndex
и reverseEach
), которые требуют определения порядка выполнения.
Теперь из прагматическогоС точки зрения, я думаю, что иногда можно использовать функции с некоторыми побочными эффектами в таких методах, как collect
.Например, для преобразования списка в [index, value]
пары transpose
и диапазон можно использовать
def list = ['a', 'b', 'c']
def enumerated = [0..<list.size(), list].transpose()
assert enumerated == [[0,'a'], [1,'b'], [2,'c']]
или даже inject
def enumerated = list.inject([]) { acc, val -> acc << [acc.size(), val] }
Но collect
и счетчик тоже помогают, и я думаю, что результат наиболее читабелен:
def n = 0, enumerated = list.collect{ [n++, it] }
Теперь этот пример не имеет смысла, если Groovy предоставит collect
и аналогичныеметоды с функцией index-value-param (см. выпуск Jira ), но это своего рода показывает, что иногда практичность превосходит чистоту IMO:)