Introducción

En Swift, los closures son bloques de funcionalidad autónomos que pueden ser pasados y utilizados en tu código. Los closures en Swift son similares a las funciones y pueden capturar y almacenar referencias a cualquier constante y variable del contexto en el que se definen. Esto se conoce como "capturar valores". Los closures en Swift pueden ser:

  • Globales: Definidos en un ámbito global y no capturan ningún valor.
  • Anidados: Definidos dentro de una función y pueden capturar valores de la función que los contiene.
  • Inline: Definidos en línea y pueden capturar valores del contexto circundante.

Sintaxis Básica

La sintaxis básica de un closure en Swift es similar a la de una función, pero sin el nombre de la función. Aquí hay un ejemplo simple:

{ (parametros) -> TipoDeRetorno in
    // Código del closure
}

Ejemplo Práctico

Vamos a ver un ejemplo práctico de un closure que suma dos números:

let suma: (Int, Int) -> Int = { (a: Int, b: Int) -> Int in
    return a + b
}

let resultado = suma(3, 5)
print(resultado) // Imprime 8

En este ejemplo:

  • suma es una constante que almacena un closure.
  • El closure toma dos parámetros a y b de tipo Int y retorna un Int.
  • El closure suma a y b y retorna el resultado.

Captura de Valores

Los closures pueden capturar y almacenar referencias a constantes y variables del contexto en el que se definen. Aquí hay un ejemplo:

func hacerIncrementador(incremento: Int) -> () -> Int {
    var total = 0
    let incrementador: () -> Int = {
        total += incremento
        return total
    }
    return incrementador
}

let incrementadorDeCinco = hacerIncrementador(incremento: 5)
print(incrementadorDeCinco()) // Imprime 5
print(incrementadorDeCinco()) // Imprime 10

En este ejemplo:

  • hacerIncrementador es una función que retorna un closure.
  • El closure captura y almacena la referencia a total y incremento del contexto en el que se define.

Sintaxis Simplificada

Swift permite simplificar la sintaxis de los closures en ciertos casos. Aquí hay algunas formas de simplificar:

Inferencia de Tipo

Si el tipo de un closure puede ser inferido, no es necesario especificar los tipos de los parámetros ni el tipo de retorno:

let sumaSimplificada = { (a, b) in
    return a + b
}

Retorno Implícito

Si el cuerpo del closure consiste en una sola expresión, Swift permite omitir la palabra clave return:

let sumaSimplificada = { (a, b) in a + b }

Nombres de Parámetros Implícitos

Swift proporciona nombres de parámetros implícitos, como $0, $1, $2, etc., que pueden ser utilizados para referirse a los parámetros del closure:

let sumaSimplificada = { $0 + $1 }

Ejercicios Prácticos

Ejercicio 1: Closure que Multiplica

Escribe un closure que tome dos números y retorne su producto.

let multiplicar: (Int, Int) -> Int = { (a, b) in
    return a * b
}

let resultado = multiplicar(4, 6)
print(resultado) // Imprime 24

Ejercicio 2: Closure que Filtra Números Pares

Escribe un closure que tome un array de enteros y retorne un nuevo array con solo los números pares.

let filtrarPares: ([Int]) -> [Int] = { numeros in
    return numeros.filter { $0 % 2 == 0 }
}

let numeros = [1, 2, 3, 4, 5, 6]
let pares = filtrarPares(numeros)
print(pares) // Imprime [2, 4, 6]

Conclusión

Los closures son una herramienta poderosa en Swift que te permiten encapsular funcionalidad y capturar valores del contexto en el que se definen. Con la práctica, aprenderás a utilizar closures de manera efectiva para escribir código más conciso y flexible. En el próximo tema, exploraremos las funciones de orden superior, que son funciones que toman otras funciones (o closures) como parámetros o retornan funciones.

© Copyright 2024. Todos los derechos reservados