Groovy вложенные замыкания с использованием 'it' - PullRequest
19 голосов
/ 02 марта 2010

Код внутри замыкания может ссылаться на переменную 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, даже если она им не нужна.

Ответы [ 2 ]

21 голосов
/ 02 марта 2010

Если вы определите замыкание как это

def closure = {println "i am a closure"}

Кажется, что у него нет параметров, но на самом деле у него есть один неявный параметр с именем it. Это подтверждается:

def closure = {println "i am a closure with arg $it"}
closure("foo")

который печатает

«Я замыкаюсь с Аргу Фу»

Если вы действительно хотите определить замыкание, которое принимает 0 параметров, используйте это:

def closure = {-> println "i am a closure"}

Следовательно, ваш пример можно переписать так:

2.times {
   println it 

   mywith {->
      println it
   }
}
15 голосов
/ 02 марта 2010

Я думаю, это как-то связано с формальным определением Closure Groovy:

У замыканий может быть 1 ... N аргументов, который может быть статически типизирован или нетипизированный. Первый параметр доступны через неявный нетипизированный аргумент назвал его, если нет явного аргументы названы. Если звонящий не указывает никаких аргументов, первый параметр (и, соответственно, это) будет нулевым.

Это означает, что Groovy Closure всегда будет иметь хотя бы один аргумент, называемый it (если не указано иное) и it будет нулевым, если не задан в качестве параметра.

Во втором примере вместо этого используется область действия закрывающего затвора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...