Groovy вложил закрытия с использованием 'его'

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

20
задан Mykola Golubyev 2 March 2010 в 08:09
поделиться

2 ответа

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

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

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

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

15
ответ дан 30 November 2019 в 00:00
поделиться

Если вы определите закрытие следующим образом

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

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

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

который выводит

"i am a closure with arg foo"

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

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

Поэтому ваш пример можно переписать так:

2.times {
   println it 

   mywith {->
      println it
   }
}
23
ответ дан 30 November 2019 в 00:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: