Menu
Coddy logo textTech

Retorno de Closures

Parte de la sección Lógica y Flujo del Journey de Swift de Coddy — lección 41 de 56.

Has visto que makeCounter devuelve un closure. El mismo truco te permite crear un comportamiento configurable: recibe parámetros una vez y obtén una función que los utilice muchas veces.

func multiplier(_ k: Int) -> (Int) -> Int {
    return { n in n * k }
}

let triple = multiplier(3)
let tenfold = multiplier(10)
print(triple(4))                  // 12
print(tenfold(4))                 // 40

La clausura devuelta captura k, por lo que cada llamada a multiplier(...) produce una clausura completamente nueva con su propio k.

Este patrón es el núcleo del código de "estrategia" en Swift: escribe una función que tome una configuración y devuelva un closure, luego pasa el closure a map, filter, sorted(by:), o a cualquier otro lugar donde se espere un valor con forma de función.

challenge icon

Desafío

Intermedio

Construye dos fábricas de cierres (closures):

  • greaterThan(_ k: Int) -> (Int) -> Bool: devuelve un predicado que es true cuando su argumento es estrictamente mayor que k
  • scaleBy(_ k: Int) -> (Int) -> Int: devuelve una función que multiplica su argumento por k

Lee tres líneas:

  1. Un entero threshold
  2. Un entero scale
  3. Una lista de enteros separados por comas, los nums

Imprime tres líneas:

  1. Los números por encima del umbral (filtrados con el cierre de greaterThan), unidos con ,
  2. Los mismos números, escalados (mapeados con scaleBy), unidos con ,
  3. Cuántos pasaron el filtro

Para la entrada 5 / 3 / 2,7,3,8,9, la salida es:

7,8,9
21,24,27
3

Hoja de referencia

Una fábrica de closures es una función que captura un parámetro y devuelve una nueva closure configurada por este:

func multiplier(_ k: Int) -> (Int) -> Int {
    return { n in n * k }
}

let triple = multiplier(3)
print(triple(4))   // 12

Cada llamada produce una closure completamente nueva con su propio valor capturado de k. Las closures devueltas pueden pasarse directamente a map, filter, sorted(by:), etc.:

func greaterThan(_ k: Int) -> (Int) -> Bool {
    return { n in n > k }
}

let nums = [2, 7, 3, 8, 9]
let filtered = nums.filter(greaterThan(5))  // [7, 8, 9]
let scaled = filtered.map(multiplier(3))    // [21, 24, 27]

Pruébalo tú mismo

let threshold = Int(readLine()!)!
let scale = Int(readLine()!)!
let nums = readLine()!.components(separatedBy: ",").map { Int($0)! }

// TODO: mayorQue, escalarPor; filtrar luego mapear; imprimir unidos y contar
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Lógica y Flujo