【问题标题】:Groovy nested closures with using 'it'使用 'it' 的 Groovy 嵌套闭包
【发布时间】:2010-03-02 08:09:45
【问题描述】:

闭包内的代码可以引用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 变量,即使它们不需要它。

【问题讨论】:

    标签: groovy


    【解决方案1】:

    如果你这样定义一个闭包

    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
       }
    }
    

    【讨论】:

    • 谢谢。显式零参数闭包在 mini-dsls 中看起来不太好。
    • 所以我相信在这种情况下,在 mywith 嵌套闭包中打印的 it 变量是 free variable
    【解决方案2】:

    我认为这与 Groovy 的 formal Closure definition 有关:

    闭包可能有 1...N 个参数, 可以是静态类型的或 无类型。第一个参数是 通过隐式无类型可用 如果没有明确的参数命名它 参数被命名。如果来电者 没有指定任何参数, 第一个参数(并且,通过扩展, 它)将为空。

    这意味着 Groovy 闭包将始终具有至少一个参数,称为 it(如果没有另外指定),如果没有作为参数给出,it 将为 null .

    第二个例子使用封闭闭包的作用域。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-10
      • 1970-01-01
      • 2021-10-21
      • 2019-10-08
      • 1970-01-01
      • 2011-10-15
      • 1970-01-01
      相关资源
      最近更新 更多