Groovy Operators

Control Statements

Groovy File Handling

Groovy Error & Exceptions

Groovy Multithreading

Groovy Synchronization

Groovy - Closure as Arguments



Passing closure as arguments enables groovy as functional programming styles. It leads to a concise and expressive code. We can pass a block of code as a parameter to methods which then can be used to execute later.

Passing Closure as Arguments

We can pass a anonymous closure as well as named closure as parameter.

Example.groovy

// method accepting a closure
def execute(String message, Closure action) {
    println "About to execute action: $message"
    action.call() // Execute the closure
    println "Action completed."
}

// Passing a closure literal
execute("Printing a message") {
    println "Hello from the closure!"
}

// define a named closure
def myClosure = {
    println "This is a named closure."
}

// Pass the named closure
execute("Using a named closure", myClosure)

Output

When we run the above program, we will get the following result.

About to execute action: Printing a message
Hello from the closure!
Action completed.
About to execute action: Using a named closure
This is a named closure.
Action completed.

Usage of Implicit it Parameter

If a closure is accepting only single parameter, groovy provides an implicit parameter named it in case parameter is not explicitly specified.

Example.groovy

// define a method accepting a closure
def process(List data, Closure processor) {
   // item is explicitly defined
   data.each { item ->  processor(item)  }
}

// pass a closure
process([1, 2, 3]) { number -> println "Processing: $number" }

def processImplicitly(List data, Closure processor) {
   // using implicit parameter "it"
   data.each { processor(it) }
}

// process list using implicit "it"
processImplicitly([10, 20, 30]) { println "Implicitly processing: $it" }

// using trailing closure with "it"
[100, 200, 300].each { println "Shorter: $it" }

Output

When we run the above program, we will get the following result.

Processing: 1
Processing: 2
Processing: 3
Implicitly processing: 10
Implicitly processing: 20
Implicitly processing: 30
Shorter: 100
Shorter: 200
Shorter: 300

We can use named parameters in any order, groovy automatically handles them.

Example.groovy

// define a method accepting named parameter and a positional parameter
def printStudent(Map student, String school){
   println "name : ${student.name}, id : ${student.id}, school: $school"
}

// call method with named parameters in different positions
printStudent(name : "Julie", id : 12, "St. Convent Public School")
printStudent(id : 13, "St. Convent Public School",name : "Robert")
printStudent("St. Convent Public School",name : "Adam", id : 14)

Output

When we run the above program, we will get the following result.

name : Julie, id : 12, school: St. Convent Public School
name : Robert, id : 13, school: St. Convent Public School
name : Adam, id : 14, school: St. Convent Public School

Advantages of Closure as Arguments

  • Parameterization of Behavior − You can pass different code to behave differently to same method making it more flexible and reusable.

  • Abstraction of Control Flow − Using closure as arguments, functional programming patterns like callbacks, iteration etc can be easily implemented.

  • DSL, Domain Specific Language − Trailing closure, delegation can be used to create expressive and readable DSL,Domain-Specific Language constructs.

  • Functional Programming − Use of Closures as arguments enables functional programming constructs like higher order functions, which can take another function as an argument.

Advertisements