Search code examples
groovyclosures

Iterate and print content of groovy closures


In a loop I create 4 closures and add them to a list:

closureList = []
for (int i=0; i<4; i++) {
    def cl = {
        def A=i;
    }
    closureList.add(cl)
}
closureList.each() {print  it.call()println "";};

This results in the following output:

4
4
4
4

But I would have expected 0,1,2,3 instead. Why does the 4 closures have the same value for A?


Solution

  • Yeah, this catches people out, the free variable i is getting bound to the last value in the for loop, not the value at the time the closure was created.

    You can either, change the loop into a closure based call:

    closureList = (0..<4).collect { i ->
        { ->
            def a = i
        }
    }
    closureList.each { println  it() }
    

    Or create an extra variable that gets re-set every time round the loop, and use that:

    closureList = []
    
    for( i in (0..<4) ) {
        int j = i
        closureList << { ->
            def a = j
        }
    }
    closureList.each { println  it() }
    

    In both of these variants the variable closed by the closure is created afresh each time round the loop, so you get the result you'd expect