Menu
Coddy logo textTech

Capturando Valores

Parte da seção Lógica e Fluxo do Journey de Swift da Coddy — lição 40 de 56.

Um closure lembra as variáveis que estavam no escopo quando foi criado. O corpo do closure pode lê-las e até modificá-las mais tarde, mesmo após a função externa ter retornado. Isso é chamado de captura.

func makeCounter() -> () -> Int {
    var count = 0
    return {
        count += 1
        return count
    }
}

let next = makeCounter()
print(next())                    // 1
print(next())                    // 2
print(next())                    // 3

Cada chamada makeCounter fornece um count novinho em folha, então dois contadores nunca compartilham o estado:

let a = makeCounter()
let b = makeCounter()
print(a())                       // 1
print(b())                       // 1
print(a())                       // 2

A captura é o que torna as closures mais poderosas do que funções comuns: elas carregam estado consigo. Você verá o mesmo truque em JavaScript, Python e muitas outras linguagens.

challenge icon

Desafio

Médio

Construa uma pequena fábrica de contadores.

Defina uma função makeCounter(start: Int, step: Int) que retorna uma closure do tipo () -> Int. Cada chamada para a closure retorna o próximo valor: a primeira chamada retorna start, a próxima retorna start + step, a próxima start + 2*step, e assim por diante.

Leia três inteiros da entrada: start, step, e n. Construa um contador com start e step, então chame-o n vezes e imprima cada resultado em sua própria linha.

Para a entrada 5 / 3 / 4, a saída é:

5
8
11
14

Folha de consulta

Closures capturam variáveis de seu escopo circundante, carregando estado mesmo após a função externa retornar:

func makeCounter() -> () -> Int {
    var count = 0
    return {
        count += 1
        return count
    }
}

let next = makeCounter()
print(next()) // 1
print(next()) // 2

Cada chamada para a função de fábrica cria uma variável capturada independente — dois contadores nunca compartilham estado.

Experimente você mesmo

let start = Int(readLine()!)!
let step = Int(readLine()!)!
let n = Int(readLine()!)!

// TODO: makeCounter(start:step:) -> () -> Int que captura o valor atual
// então chame-a n vezes e imprima cada resultado
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Lógica e Fluxo