Groovy:如何记住闭包';执行之间的变量值是多少?

Groovy:如何记住闭包';执行之间的变量值是多少?,groovy,closures,Groovy,Closures,我希望能够做到以下几点: def closure = { def a // create new variable, but ONLY if not created yet if (a == null) { a = 0 } a++ print a } closure() // prints 1 closure() // prints 2 closure() // prints 3, etc... def closure = { if( !delegate.

我希望能够做到以下几点:

def closure = { 
  def a // create new variable, but ONLY if not created yet
  if (a == null) {
    a = 0
  }
  a++
  print a
}

closure() // prints 1
closure() // prints 2
closure() // prints 3, etc...
def closure = { 
  if( !delegate.hasProperty( 'a' ) ) {
    println "Adding a to delegate"
    delegate.metaClass.a = 0
  }
  delegate.a++
  println delegate.a
}

closure() // prints 1
closure() // prints 2
closure() // prints 3, etc...

我想在闭包内部创建变量,而不是在外部作用域中创建变量。

您可以这样做:

def closure = { 
  def a // create new variable, but ONLY if not created yet
  if (a == null) {
    a = 0
  }
  a++
  print a
}

closure() // prints 1
closure() // prints 2
closure() // prints 3, etc...
def closure = { 
  if( !delegate.hasProperty( 'a' ) ) {
    println "Adding a to delegate"
    delegate.metaClass.a = 0
  }
  delegate.a++
  println delegate.a
}

closure() // prints 1
closure() // prints 2
closure() // prints 3, etc...

但这是一个令人讨厌的副作用,如果你不小心,它会严重地伤害你(任何类型的多线程都会失败)

这可能是一个无效的答案,但外部范围不需要是全局的;例如,它可以位于函数内部,甚至可以位于匿名函数内部,如:

def closure = {
    def a
    return { 
        if (a == null) a = 1
        println a++ 
    }
}()

closure() // prints 1
closure() // prints 2
closure() // prints 3, etc...
周围匿名函数的目的只是为
a
变量赋予作用域,而不污染全局作用域。请注意,该函数在定义后立即进行求值


这样,
a
的范围实际上是该闭包的“私有”范围(因为它是外部功能评估后唯一引用它的范围)。但是变量是在第一次
closure()
调用之前定义的,因此这可能不是您想要的。

为什么不希望在外部范围中定义变量?在我看来,这将是一个简单而有效的解决方案:S+1 genius:-)您所需要的只是
def closure={a=1;{->println a++}()
您可以感受到javascript体验的背后;)@tim_yates(你错过了一个
def
=P)是的,我一开始就是这么做的,但后来我添加了
if
来初始化那里的变量,使它与OP要求的更相似(可能他想使用比int更复杂的东西,而且初始化很昂贵)@fixitagain One不会简单地离开回调地狱,呵呵,你不需要def。至少不是在groovy控制台中