Подтвердить что ты не робот

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, даже если она не нужна.

4b9b3361

Ответ 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
   }
}