tags:

views:

408

answers:

4

is there a way to 'break' out of a groovy closure.

maybe something like this:

[1, 2, 3].each { 
  println(it)
  if (it == 2)
    break 
}
A: 

You can throw an exception:

try {
    [1, 2, 3].each { 
        println(it)
        if (it == 2)
            throw new Exception("return from closure") 
    }
} catch (Exception e) { }

Use could also use "findAll" or "grep" to filter out your list and then use "each".

[1, 2, 3].findAll{ it < 3 }.each{ println it }
John Wagenleitner
+1  A: 

Take a look at Best pattern for simulating continue in groovy closure for an extensive discussion.

Robert Munteanu
A: 

Edited.

[1, 2, 3].each { 
  if (it == 2) return
  println(it)
}

Think of the closure like a little method. How would you break out of a method? You return. Return will break out of the closure.

You cannot break out of the iteration just as you couldn't break out of the following code.

doThings([0,1,3])

void doThings(List things) {
    for (i in things) {
        printIt(i)
    }
}

void printIt(Object it) {
    if(it == 2) break // This is not possible beacuse you arn't inside a loop
    println it
}

This almost exactly what Groovy is doing when you call the each METHOD and pass it a closure.

Something you might want to consider for your particular case: the find or findAll methods.

[1,2,3].findAll { it < 2 }.each { println it }

I hope this helps you understand what is going on.

Tiggerizzy
Your code prints 1, 2, 3 - return will not return from a closure.
John Wagenleitner
Just wanted to clarify that return will not "break" out of the closure, it will just return the method executing the closure. In the above case, had there been a println below the return it only would have printed for 1 and 3, however 1, 2 and 3 still would have been printed by the first println.
John Wagenleitner
I think you are confused. "each" is a METHOD that takes a closure as an argument. Then iterates over the collection calling your closure and passing in the current object as an argument to the closure.I have updated my answer to make this more clear.
Tiggerizzy
Yes, I was confused it was late :p. I think the OP wanted to return from the method that was executing the closure and was just trying to point out that "return" does not do that. By changing the code it prints the expected results, but I don't think it's what the OP had in mind.
John Wagenleitner
+1  A: 

I often forget that Groovy implements an "any" method.

[1, 2, 3].any {
println it
return (it == 2) }​

J. Skeen