Retourner des closures
Fait partie de la section Logique et Flux du Journey Swift de Coddy — leçon 41 sur 56.
Vous avez vu makeCounter retourner une closure. La même astuce vous permet de construire un comportement configurable : prenez des paramètres une fois, et obtenez en retour une fonction qui les utilise plusieurs fois.
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)) // 40La closure retournée capture k, donc chaque appel à multiplier(...) produit une toute nouvelle closure avec son propre k.
Ce patron est au cœur du code de « stratégie » en Swift : écrivez une fonction qui prend une configuration et renvoie une closure, puis passez la closure à map, filter, sorted(by:), ou partout ailleurs où une valeur de type fonction est attendue.
Défi
MoyenConstruisez deux fabriques de fermetures (closure factories) :
greaterThan(_ k: Int) -> (Int) -> Bool: renvoie un prédicat qui esttruelorsque son argument est strictement supérieur àkscaleBy(_ k: Int) -> (Int) -> Int: renvoie une fonction qui multiplie son argument park
Lisez trois lignes :
- Un entier
threshold - Un entier
scale - Une liste d'entiers séparés par des virgules, les
nums
Affichez trois lignes :
- Les nombres supérieurs au seuil (filtrez avec la fermeture de
greaterThan), joints par, - Ces mêmes nombres, mis à l'échelle (mappez avec
scaleBy), joints par, - Le nombre d'éléments qui ont été conservés
Pour l'entrée 5 / 3 / 2,7,3,8,9, la sortie est :
7,8,9
21,24,27
3Aide-mémoire
Une fabrique de fermetures est une fonction qui capture un paramètre et renvoie une nouvelle fermeture configurée par celui-ci :
func multiplier(_ k: Int) -> (Int) -> Int {
return { n in n * k }
}
let triple = multiplier(3)
print(triple(4)) // 12Chaque appel produit une toute nouvelle fermeture avec sa propre valeur capturée de k. Les fermetures renvoyées peuvent être passées directement à 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]Essayez vous-même
let threshold = Int(readLine()!)!
let scale = Int(readLine()!)!
let nums = readLine()!.components(separatedBy: ",").map { Int($0)! }
// TODO: greaterThan, scaleBy; filtrer puis mapper; afficher les éléments joints et le compte
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Logique et Flux
1Les chaînes de caractères en profondeur
Comptage et indicesCasse et nettoyageRecherche dans les chaînesDécoupage et jointureRemplacement de sous-chaînesRécapitulatif - Vérification du nom d'utilisateur4Ensembles
Création d'ensemblesUnion et intersectionSoustraction et différence symétriqueSous-ensemble et sur-ensembleRécapitulatif - Filtre de tags7Projet - Suivi d'habitudes
Aperçu du projetMarquer comme terminé10Projet - Moteur de quiz
Présentation du projetPoser des questions2Intervalles et Pas
Fermé vs Semi-ouvertLe PasMéthodes d'intervalleIntervalles dans un SwitchRécapitulatif - Grille de calendrier5Fonctions d'ordre supérieur, Partie 1
MapFilterReduceChaînage de map, filter, reduceRécapitulatif - Statistiques de mots8Closures
Les bases des closuresClosures finalesCapture de valeursRetourner des closuresOrdre supérieur personnaliséRécapitulatif - Pipeline Builder