使用'it'的Groovy嵌套闭包

Myk*_*yev 20 groovy

闭包内的代码可以引用it变量.

8.times { println it }
Run Code Online (Sandbox Code Playgroud)

要么

def mywith(Closure closure) {
   closure()
}

mywith { println it }
Run Code Online (Sandbox Code Playgroud)

记住这种行为,您不能指望打印下面的代码 0011

2.times {
   println it 

   mywith {
      println it
   }
}
Run Code Online (Sandbox Code Playgroud)

相反,我必须写

2.times { i ->
   println i 

   mywith {
      println i
   }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:为什么没有参数的闭包覆盖it变量,即使它们不需要它.

Dón*_*nal 23

如果你定义这样的闭包

def closure = {println "i am a closure"}
Run Code Online (Sandbox Code Playgroud)

它似乎没有参数,但实际上它有一个名为的隐式参数it.这证实了:

def closure = {println "i am a closure with arg $it"}
closure("foo")
Run Code Online (Sandbox Code Playgroud)

打印

"我是arg foo的关闭"

如果你真的想要定义一个带0参数的闭包,请使用:

def closure = {-> println "i am a closure"}
Run Code Online (Sandbox Code Playgroud)

因此,您的示例可以重写为:

2.times {
   println it 

   mywith {->
      println it
   }
}
Run Code Online (Sandbox Code Playgroud)


Daf*_*aff 15

我认为它与Groovy 的正式Closure定义有关:

闭包可能有1 ... N个参数,可以是静态类型或非类型化.如果没有命名显式参数,则第一个参数可通过名为it的隐式无类型参数获得.如果调用者没有指定任何参数,则第一个参数(以及扩展名为)将为null.

这意味着,一个Groovy闭包总是至少有一个说法,叫做(如果不是另有规定)和如果不是作为一个参数给出将是空的.

第二个示例使用封闭闭包的范围.