Menu
Coddy logo textTech

Trailing Closures

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

Quando uma closure é o último argumento de uma função, você pode escrevê-la fora dos parênteses. Esta é a forma de trailing-closure, e é assim que o código Swift é lido naturalmente.

let nums = [1, 2, 3]
// Forma padrão
let a = nums.map({ $0 * 2 })
// Forma de trailing closure
let b = nums.map { $0 * 2 }

Se a closure for o único argumento, os parênteses desaparecem também. É por isso que tudo o que você viu até agora parece uma estrutura de controle personalizada.

Você pode escrever suas próprias funções para receber closures da mesma forma:

func repeatN(_ n: Int, action: () -> Void) {
    for _ in 0..<n {
        action()
    }
}
repeatN(3) {
    print("hi")
}

A forma de trailing-closure faz com que repeatN(3) { ... } seja lido como um loop nativo. Esse é o objetivo: estruturas de controle que você mesmo constrói pareçam exatamente como as da biblioteca padrão.

challenge icon

Desafio

Fácil

Defina uma função collect que:

  • Recebe um inteiro n e um closure builder: (Int) -> String
  • Chama builder para cada i de 1 até n (inclusive) e retorna o array de strings resultantes

Leia um inteiro da entrada padrão (stdin), chame collect com esse inteiro usando um trailing closure que produz "i=<i>" para cada valor, e imprima o resultado concatenado com ,.

Para a entrada 4, a saída é i=1,i=2,i=3,i=4.

Folha de consulta

Sintaxe de trailing closure: quando um closure é o último argumento, ele pode ser escrito fora dos parênteses. Se for o único argumento, os parênteses são omitidos inteiramente.

let nums = [1, 2, 3]
let a = nums.map({ $0 * 2 }) // padrão
let b = nums.map { $0 * 2 }  // trailing closure

Funções personalizadas podem aceitar closures da mesma forma, fazendo com que pareçam estruturas de controle integradas:

func repeatN(_ n: Int, action: () -> Void) {
    for _ in 0..<n {
        action()
    }
}
repeatN(3) {
    print("hi")
}

Experimente você mesmo

let n = Int(readLine()!)!

// TODO: func collect(_ n:Int, builder:(Int)->String) -> [String]
// então chame collect(n) { ... } e imprima unido com ","
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