Retornando Closures
Parte da seção Lógica e Fluxo do Journey de Swift da Coddy — lição 41 de 56.
Você viu o makeCounter retornar um closure. O mesmo truque permite que você construa um comportamento configurável: receba parâmetros uma vez e obtenha de volta uma função que os utiliza muitas vezes.
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)) // 40A closure retornada captura k, então cada chamada de multiplier(...) produz uma closure totalmente nova com seu próprio k.
Este padrão é o cerne do código de "estratégia" em Swift: escreva uma função que recebe uma configuração e retorna um closure, então passe o closure para map, filter, sorted(by:), ou qualquer outro lugar onde um valor em formato de função seja esperado.
Desafio
MédioConstrua duas fábricas de closures:
greaterThan(_ k: Int) -> (Int) -> Bool: retorna um predicado que étruequando seu argumento é estritamente maior quekscaleBy(_ k: Int) -> (Int) -> Int: retorna uma função que multiplica seu argumento pork
Leia três linhas:
- Um número inteiro
threshold - Um número inteiro
scale - Uma lista de inteiros separados por vírgula, os
nums
Imprima três linhas:
- Os números acima do limite (filtre com a closure de
greaterThan), unidos por, - Os mesmos números, escalonados (mapeie com
scaleBy), unidos por, - Quantos números passaram pelo filtro
Para a entrada 5 / 3 / 2,7,3,8,9, a saída é:
7,8,9
21,24,27
3Folha de consulta
Uma fábrica de closures (closure factory) é uma função que captura um parâmetro e retorna uma nova closure configurada por ele:
func multiplier(_ k: Int) -> (Int) -> Int {
return { n in n * k }
}
let triple = multiplier(3)
print(triple(4)) // 12Cada chamada produz uma closure novinha em folha com seu próprio valor capturado de k. As closures retornadas podem ser passadas diretamente para 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]Experimente você mesmo
let threshold = Int(readLine()!)!
let scale = Int(readLine()!)!
let nums = readLine()!.components(separatedBy: ",").map { Int($0)! }
// TODO: maiorQue, escalarPor; filtrar depois mapear; imprimir unidos e contar
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
1Strings a Fundo
Contagem e ÍndicesCase e TrimBusca em StringsDivisão e JunçãoSubstituindo SubstringsRecapitulação - Verificação de Nome de Usuário4Conjuntos
Criando ConjuntosUnião e InterseçãoSubtração e Diferença SimétricaSubconjunto e SuperconjuntoRecapitulação - Filtro de Tags7Projeto - Monitor de Hábitos
Visão Geral do ProjetoMarcar como Concluído10Projeto - Mecanismo de Quiz
Visão Geral do ProjetoFazer Perguntas2Intervalos e Strides
Fechado vs Meio-AbertoStrideMétodos de IntervaloIntervalos no SwitchRecapitulação - Grade de Calendário5Funções de Ordem Superior Parte 1
MapFilterReduceEncadeando map, filter, reduceRecapitulação - Estatísticas de Palavras