APPENDIX B: Introduction to Groovy 417
Here is the output:
Hello world
Hello default world
Closures always have a return value. The value may be specified via one or more explicit return
statements in the closure body, as illustrated in Listing B-28, or as the value of the last executed
statement if return is not explicitly specified, as illustrated in Listing B-29.
Listing B-28. Using Return Keyword
def sum = {list -> return list.sum()}
assert sum([2,2]) == 4
Listing B-29. Return Keyword Optional
def sum = {list -> list.sum()}
assert sum([2,2]) == 4
To understand closures, you have to understand the concept of free variables. A closure is formed
when the body of a function refers to one or more free variables. Free variables are variables that
are not local to the function and are not passed as arguments to the function but are defined in the
enclosing scope where the function is defined. Thus, closures refer to variables not listed in their
parameter list (free variables). They are “bound” to variables within the scope where they are defined.
Listing B-30 illustrates this.
Listing B-30. Free Variables
def myConst = 5
def incByConst = { num -> num + myConst }
assert incByConst(10) == 15
The runtime “closes over” the free variable (myConst in Listing B-30) so that it is available when the
function is executed. That is, the compiler creates a closure that envelops the external context of
free variables and binds them.
Implicit Variables
Within a Groovy closure, an implicit variable (it) is defined that has a special meaning. If only one
argument is passed to the closure, the arguments list and the -> symbol can be omitted, and the
closure will have access to it, which represents that one argument, illustrated in Listing B-31.
Listing B-31. Using it
def closure = {println "Hello ${it}"}
closure.call('world')
Hello world