groovy

Closures

Closure with explicit parameters

def addNumbers = { a, b -> a + b }
addNumbers(-7, 15) // returns 8

Closure with implicit parameters

['cat', 'dog', 'fish'].collect { it.length() }

it is the default name of the parameter if you have a single parameter and do not explicitly name the parameter. You can optionally declare the parameter as well.

['cat', 'dog', 'fish'].collect { animal -> animal.length() }

Converting Methods to Closures

A method can be converted to a closure using the & operator.

def add(def a, def b) { a + b }    

Closure addClosure = this.&add
assert this.add(4, 5) == addClosure(4, 5)

Closure with custom target for method calls with implicit receiver

class MyHello {
  def sayHello() {
    "Hello, world"
  }
}

def cl = { sayHello() }
cl() // groovy.lang.MissingMethodException    
cl.delegate = new MyHello()
cl(); // "Hello, world"

Used extensively by Groovy DSLs.

Wrapping behavior around a closure with a method

There are frequent behavior patterns that can result in a lot of boilerplate code. By declaring a method that takes a Closure as a parameter, you can simplify your program. As an example, it is a common pattern to retrieve a database connection, start a transaction, do work, and then either commit the transaction, or rollback the connection (in case of error), then finally close the connection:

def withConnection( String url, String user, String pass, Closure closure) {
    Connection conn = null
    try {
        conn = DriverManager.getConnection( url, user, pass )
        closure.call( conn )
        conn.commit()
    } catch (Exception e) {
        log.error( "DB Action failed", e)
        conn.rollback()
    } finally {
        conn?.close()
    }
}


withConnection( DB_PATH, DB_USER, DB_PASS ) { Connection conn ->
    def statement = conn.createStatement()
    def results = statement.executeQuery( 'SELECT * FROM users' )
    // ... more processing ...
}

Create closures, assign to properties and call

Let’s create a map and a closure to print hello

def exMap = [:]

def exClosure = {
    println "Hello"
}

Assign closure to a property in map

exMap.closureProp = exClosure

Calling closure

exMap.closureProp.call()

Output

Hello

Another Example - Lets create a class with basic property and assign same closure to object of it

class Employee {
    def prop
}

def employee = new Employee()

employee.prop = exClosure

Call closure through that property

employee.prop.call()

Output

Hello

This modified text is an extract of the original Stack Overflow Documentation created by the contributors and released under CC BY-SA 3.0 This website is not affiliated with Stack Overflow