简体   繁体   English

Groovy:如何记住执行之间的闭包变量值?

[英]Groovy: How to remember closure's variable value between executions?

I would like to be able to do something like this: 我希望能够做到这样的事情:

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

I want to create the variable INSIDE the closure, not in outer scope. 我想在闭包中创建变量INSIDE,而不是在外部作用域中。

This may be an invalid answer but the outer scope doesn't need to be global; 这可能是无效的答案,但外部范围不需要是全局的; it can be inside a function for example, or even an anonymous function like: 它可以在一个函数内部,或者甚至是一个匿名函数,如:

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

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

The purpose of the surrounding anonymous function is just to give scope to the a variable without polluting the global scope. 周围的匿名函数的目的只是给范围的a变量,不污染全局范围。 Notice that that function is being evaluated immediately after its definition. 请注意,该函数在定义后立即进行评估。

This way, the scope of a is effectively "private" to that closure (as it is the only one with a reference to it once the outer function has been evaluated). 这样,范围a是有效地“私人”来表示的封闭件(因为它是唯一一个与它的一个引用一旦外部函数已经被评估)。 But the variable is being defined before the first closure() call, so this might not be what you are looking for. 但是变量是第一次调用closure() 之前定义的,所以这可能不是你想要的。

You can do something like this: 你可以这样做:

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

But that's a nasty side-effect, and if you don't take care it's going to bite you hard (and any sort of multi-threading will fail horribly) 但这是一个令人讨厌的副作用,如果你不小心它会咬你(并且任何类型的多线程都会失败)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM