Groovy вложенные замыкания с использованием 'it'
Кодовые замыкания могут ссылаться на переменную it
.
8.times { println it }
или
def mywith(Closure closure) {
closure()
}
mywith { println it }
С учетом этого поведения вы не можете ожидать, что следующий код будет напечатан 0011
2.times {
println it
mywith {
println it
}
}
И вместо этого я должен написать
2.times { i ->
println i
mywith {
println i
}
}
Мой вопрос: почему закрытие без параметров переопределяет переменную it
, даже если она не нужна.
Ответы
Ответ 1
Я думаю, что это имеет какое-то отношение к формальному определению закрытия Groovy:
Закрытие может иметь 1... N аргументов, которые могут быть статически типизированы или нетипизированный. Первый параметр доступный через неявный нетипизированный аргумент назвал его, если нет явного аргументы называются. Если вызывающий не указывает никаких аргументов, первый параметр (и, он) будет null.
Это означает, что Groovy Closure всегда будет иметь хотя бы один аргумент, называемый им (если не указан иначе), и он будет null, если не указан как параметр.
Второй пример использует область закрывающего замыкания.
Ответ 2
Если вы определите замыкание, подобное этому
def closure = {println "i am a closure"}
У него нет параметров, но на самом деле он имеет один неявный параметр с именем it
. Это подтверждается:
def closure = {println "i am a closure with arg $it"}
closure("foo")
который печатает
"Я - замыкание с arg foo"
Если вы действительно хотите определить замыкание, которое принимает 0 параметров, используйте это:
def closure = {-> println "i am a closure"}
Поэтому ваш пример можно переписать как:
2.times {
println it
mywith {->
println it
}
}