Return Statements in Closures



>> Tuesday, December 21, 2010

I found an interesting little "quirk" that I was not expecting with Groovy today having to do with return statements in a closure.

Let's say I have some code like this:

String someMethod(){
def myList = ["1", "a", "test", "z"]
myList.each{
println "in each loop for: " + it
if(it == "test"){
println "\tfound"
return it
}
println "\tafter if"
}
}

def value = someMethod()
println value;


The output is:
in each loop for: 1
after if
in each loop for: a
after if
in each loop for: test
found
in each loop for: z
after if
[1, a, test, z]


I was hoping for this:
in each loop for: 1
after if
in each loop for: a
after if
in each loop for: test
found
test

Where it would return from the method once the value is found. It turns out each{} doesn't work this way. I am sure there are good (complicated) reasons for this, but for now I'm just going to change my method to use a good old for loop.

String someMethod2(){
def myList = ["1", "a", "test", "z"]
for(int i = 0; i < myList.size; i++){
println "in each loop for: " + myList[i]
if(myList[i] == "test"){
println "\tfound"
return myList[i]
}
println "\tafter if"
}
}

1 comments:

Hamlet D'Arcy December 22, 2010 at 4:51 AM  

return is always a "local return". To have it otherwise would require support for "non local return" which brings complexity because you'll need a way in the language to differentiate between local and non local return. This was a big issue for the Java 7 closures proposals back a few years ago.

Anyway, for each{} methods you are right to use a for-loop instead because it is faster and more idiomatic Java. However, there is also the find method, which is what you should use otherwise: http://is.gd/jdnNe

Post a Comment

  © Blogger template Webnolia by Ourblogtemplates.com 2009

Back to TOP