Groovy & Gradle: JVM Automation and Build Engineering · Lección

Comprensión de los closures de Groovy

Aprenda el concepto de closure, cómo definirlos y sus versátiles aplicaciones en Groovy.

Lección 2 de 411 pasos

Comprensión de los closures de Groovy es una lección gratuita de Groovy & Gradle: JVM Automation and Build Engineering en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Groovy & Gradle: JVM Automation and Build Engineering, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Groovy & Gradle: JVM Automation and Build Engineering incluye 4 lecciones en total.

Partes de esta lección aún no han sido traducidas y se muestran en inglés.

What Are Groovy Closures?

Welcome to the world of Groovy closures! A closure is essentially a block of code that can be treated like a variable.

Think of it as a mini-function you can define, store, and pass around. Closures are a powerful feature that make Groovy code very flexible and concise.

  • They are first-class citizens, meaning they can be assigned to variables, passed as arguments, and returned from methods.
  • They can capture variables from their surrounding scope, even after that scope has finished executing.

Basic Closure Syntax

Defining a closure is straightforward. You enclose your code block within curly braces {}. Let's see a simple example:

class Main {
  static void main(String[] args) {
    // Define a simple closure
    def sayHello = {
      println "Hello from a closure!"
    }

    // Call (execute) the closure
    sayHello()
  }
}

Closures with Parameters

Just like methods, closures can accept parameters. You list the parameters before the -> (arrow) operator, followed by the closure's body.

This allows your closure to perform operations based on the input it receives.

class Main {
  static void main(String[] args) {
    // Closure that takes two parameters
    def add = { num1, num2 ->
      return num1 + num2
    }

    // Call the closure with arguments
    def result = add(10, 5)
    println "Sum: ${result}"

    // You can also omit 'return' for the last statement
    def multiply = { a, b -> a * b }
    println "Product: ${multiply(4, 3)}"
  }
}

The 'it' Keyword

When a closure takes exactly one parameter, Groovy provides a special implicit variable called it. You don't need to declare it explicitly.

This makes single-parameter closures even more concise and readable, especially when used with collection methods.

class Main {
  static void main(String[] args) {
    // Closure using 'it' for a single parameter
    def square = { it * it }

    println "Square of 7: ${square(7)}"

    def greetPerson = { "Hello, ${it}!" }
    println greetPerson("Alice")
  }
}

Closures as Method Arguments

One of the most common and powerful uses of closures in Groovy is passing them as arguments to methods. Many Groovy methods, especially those on collections, are designed to accept closures.

If a closure is the last argument to a method, you can place it outside the parentheses, making the code look very clean and DSL-like.

class Main {
  static void main(String[] args) {
    def numbers = [1, 2, 3, 4, 5]

    // Using 'each' with a closure to iterate
    numbers.each { num ->
      println "Number: ${num}"
    }

    println "---"

    // Using 'collect' with a closure to transform
    def doubledNumbers = numbers.collect { it * 2 }
    println "Doubled: ${doubledNumbers}"
  }
}

Capturing Variables: Lexical Scope

Closures have lexical scope, meaning they remember and can access variables from the scope where they were defined, even if that scope no longer exists.

This is a key characteristic that differentiates closures from regular methods and allows them to carry context with them.

class Main {
  static void main(String[] args) {
    def name = "Groovy User" // Variable in the outer scope

    def introduce = {
      // The closure 'introduce' captures 'name'
      println "My name is ${name}."
    }

    introduce() // Calls the closure, accessing 'name'

    name = "CoddyKit Enthusiast" // Change the outer variable
    introduce() // The closure still references the updated 'name'
  }
}

Modifying Captured Variables

Not only can closures access captured variables, but they can also modify them. This creates a powerful way for closures to interact with their surrounding environment.

Be mindful when modifying external variables from within closures, as it can sometimes lead to less predictable code if not managed carefully.

class Main {
  static void main(String[] args) {
    def counter = 0 // A variable to be captured

    def increment = {
      counter++ // Closure modifies the outer 'counter'
      println "Counter is now: ${counter}"
    }

    increment() // Counter: 1
    increment() // Counter: 2
    increment() // Counter: 3

    println "Final counter value: ${counter}"
  }
}

Closure 'call()' Method

While you can execute a closure by simply using parentheses (e.g., myClosure()), closures are actually instances of the groovy.lang.Closure class.

This means they also have a call() method. Using call() is equivalent to direct execution and can sometimes be useful for clarity or when dynamically invoking closures.

class Main {
  static void main(String[] args) {
    def greet = { name ->
      println "Hello, ${name}!"
    }

    // Direct execution
    greet("World")

    // Execution using the call() method
    greet.call("Groovy")

    def add = { a, b -> a + b }
    println add.call(5, 7)
  }
}

Practical Use: Filtering Lists

Let's put closures to work with a practical example: filtering elements from a list. Groovy's collection methods, like findAll, are perfect for this.

You provide a closure that defines the condition for inclusion, and findAll returns a new list containing only the elements that satisfy that condition.

class Main {
  static void main(String[] args) {
    def numbers = [10, 25, 12, 30, 5, 45, 20]

    // Find numbers greater than 20
    def largeNumbers = numbers.findAll { it > 20 }
    println "Numbers > 20: ${largeNumbers}"

    // Find even numbers
    def evenNumbers = numbers.findAll { it % 2 == 0 }
    println "Even numbers: ${evenNumbers}"
  }
}

Closure Concepts Check

Which of the following statements about Groovy Closures are TRUE?

Recap: Understanding Closures

Great job! You've taken a significant step in understanding Groovy's powerful closures.

Here's a quick summary of what we covered:

  • Closures are code blocks treated as first-class citizens.
  • They use {} for definition and -> for parameters.
  • The it keyword simplifies single-parameter closures.
  • Closures are often passed as method arguments, enhancing Groovy's expressiveness.
  • They possess lexical scope, capturing and even modifying variables from their surrounding context.

In the next lesson, we'll explore how to apply closures to functional programming patterns in Groovy!

Gratis para empezar

Aprende Groovy con un tutor de IA — gratis

Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.

Cursos
12
Lecciones
48

Preguntas frecuentes

¿La lección «Comprensión de los closures de Groovy» es gratis?

Sí — el texto completo de «Comprensión de los closures de Groovy» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Groovy & Gradle: JVM Automation and Build Engineering, actualiza a CoddyKit PRO. El curso de Groovy & Gradle: JVM Automation and Build Engineering incluye 4 lecciones en total.

¿Qué aprenderé en «Comprensión de los closures de Groovy»?

Aprenda el concepto de closure, cómo definirlos y sus versátiles aplicaciones en Groovy. Practicas Groovy & Gradle: JVM Automation and Build Engineering con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Groovy & Gradle: JVM Automation and Build Engineering?

No se requiere experiencia previa. Groovy & Gradle: JVM Automation and Build Engineering en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.

¿Cuánto tiempo toma la lección «Comprensión de los closures de Groovy»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Groovy & Gradle: JVM Automation and Build Engineering?

Sí. Cada lección de Groovy & Gradle: JVM Automation and Build Engineering incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Mejoras de las colecciones de Groovy
  2. Comprensión de los closures de Groovy
  3. Patrones funcionales con Groovy
  4. Currificación y composición de closures
← Volver a Groovy & Gradle: JVM Automation and Build Engineering