Groovy: Как запомнить значение переменной замыкания между выполнениями? - PullRequest
2 голосов
/ 19 января 2012

Я хотел бы иметь возможность сделать что-то вроде этого:

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

Я хочу создать переменную ВНУТРИ замыкания, а не во внешней области видимости.

Ответы [ 2 ]

7 голосов
/ 19 января 2012

Это может быть неверный ответ, но внешняя область не должна быть глобальной; например, она может быть внутри функции или даже анонимной функции, такой как:

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() вызова, поэтому это может быть не то, что вы ищете.

1 голос
/ 19 января 2012

Вы можете сделать что-то вроде этого:

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

Но это неприятный побочный эффект, и если вы не позаботитесь, он вас сильно укусит (и любой вид многопоточностиужасно терпеть неудачу)

...