Captura de valores
Parte de la sección Lógica y Flujo del Journey de Swift de Coddy — lección 40 de 56.
Un closure recuerda las variables que estaban en su alcance cuando fue creado. El cuerpo del closure puede leerlas e incluso modificarlas más tarde, incluso después de que la función que lo rodea haya terminado su ejecución. A esto se le llama captura.
func makeCounter() -> () -> Int {
var count = 0
return {
count += 1
return count
}
}
let next = makeCounter()
print(next()) // 1
print(next()) // 2
print(next()) // 3Cada llamada a makeCounter te da un count completamente nuevo, por lo que dos contadores nunca comparten el estado:
let a = makeCounter()
let b = makeCounter()
print(a()) // 1
print(b()) // 1
print(a()) // 2La captura es lo que hace que las clausuras (closures) sean más potentes que las funciones simples: llevan el estado consigo. Verás el mismo truco en JavaScript, Python y muchos otros lenguajes.
Desafío
IntermedioConstruye una pequeña fábrica de contadores.
Define una función makeCounter(start: Int, step: Int) que devuelva un cierre (closure) de tipo () -> Int. Cada llamada al cierre devuelve el siguiente valor: la primera llamada devuelve start, la siguiente devuelve start + step, la siguiente start + 2*step, y así sucesivamente.
Lee tres números enteros de la entrada: start, step, y n. Construye un contador con start y step, luego llámalo n veces e imprime cada resultado en su propia línea.
Para la entrada 5 / 3 / 4, la salida es:
5
8
11
14Hoja de referencia
Los Closures capturan variables de su ámbito circundante, manteniendo el estado incluso después de que la función externa retorne:
func makeCounter() -> () -> Int {
var count = 0
return {
count += 1
return count
}
}
let next = makeCounter()
print(next()) // 1
print(next()) // 2Cada llamada a la función de fábrica crea una variable capturada independiente — dos contadores nunca comparten el estado.
Pruébalo tú mismo
let start = Int(readLine()!)!
let step = Int(readLine()!)!
let n = Int(readLine()!)!
// TODO: makeCounter(start:step:) -> () -> Int que capture el valor actual
// luego llámalo n veces e imprime cada resultado
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
1Strings a fondo
Conteo e índicesMayúsculas, minúsculas y TrimBúsqueda en StringsDividir y unirReemplazo de subcadenasResumen: Validación de usuario4Conjuntos
Crear conjuntosUnión e intersecciónResta y diferencia simétricaSubconjunto y superconjuntoResumen - Filtro de etiquetas7Proyecto - Seguimiento de hábitos
Descripción general del proyectoMarcar como completado10Proyecto - Motor de cuestionarios
Descripción general del proyectoHacer preguntas2Rangos e Intervalos
Cerrados vs. SemiabiertosSaltos (Stride)Métodos de RangosRangos en SwitchResumen - Cuadrícula de calendario5Funciones de orden superior Pt. 1
MapFilterReduceEncadenar map, filter, reduceResumen - Estadísticas de palabras