Closures en Swift
Apprenez à emballer des fonctionnalités pour les stocker, les réutiliser et les simplifier.
Les closures en Swift sont des blocs de code auto-contenus qui peuvent être passés et utilisés dans votre code. Elles sont similaires aux fonctions, mais elles peuvent capturer et stocker des références aux variables et constantes de leur contexte environnant. En d'autres termes, une closure peut capturer des valeurs des variables locales autour d'elle, ce qui la rend très puissante pour certains types de programmation, comme les callbacks, les filtres, les mappages, etc.
Syntaxe de Base d'une Closure
La syntaxe d'une closure peut être compacte ou plus détaillée, selon la situation. Voici la syntaxe de base :
{ (parameters) -> returnType in
// Code à exécuter
}
parameters: Les paramètres que la closure accepte, identiques à ceux des fonctions.returnType: Le type de la valeur retournée par la closure. Il peut être omis si la closure ne retourne rien.in: Mot-clé qui sépare la liste des paramètres et le type de retour du corps de la closure.
Exemples de Closures
Closure simple qui additionne deux nombres
let sumClosure = { (a: Int, b: Int) -> Int in
return a + b
}
let result = sumClosure(3, 5)
print(result) // Affiche : 8
Dans cet exemple :
- La closure
sumClosureaccepte deux paramètresaetbde typeInt. - Elle retourne un
Intqui est la somme deaetb. sumClosureest ensuite appelée avec les arguments3et5.
Closure sans paramètres ni retour
let greetClosure = {
print("Hello, world!")
}
greetClosure() // Affiche : "Hello, world!"
Cette closure n'accepte aucun paramètre et ne retourne aucune valeur. Elle se contente d'exécuter le code à l'intérieur, qui ici affiche un message.
Closures comme Paramètres de Fonction
Les closures sont souvent utilisées comme paramètres dans des fonctions, notamment pour des opérations asynchrones ou des transformations de collections.
Exemple avec sort :
let numbers = [5, 2, 9, 1, 7]
let sortedNumbers = numbers.sorted(by: { (a: Int, b: Int) -> Bool in
return a < b
})
print(sortedNumbers) // Affiche : [1, 2, 5, 7, 9]
Dans cet exemple :
- La méthode
sorted(by:)utilise une closure pour déterminer l'ordre de tri. - La closure compare deux éléments et retourne un
Boolindiquant si le premier élément doit précéder le second.
Syntaxe Réduite des Closures
Swift permet de simplifier la syntaxe des closures, surtout dans les cas où le contexte est évident.
Exemple avec Inference de Type :
let sortedNumbers = numbers.sorted(by: { a, b in a < b })
Swift peut inférer les types des paramètres a et b, donc vous pouvez omettre leur type et le type de retour.
Utilisation de $0, $1, etc. :
let sortedNumbers = numbers.sorted(by: { $0 < $1 })
Swift fournit des noms abrégés pour les paramètres de closure ($0 pour le premier paramètre, $1 pour le second, etc.), ce qui permet de rendre la closure encore plus concise.
Trailing Closure Syntax :
Si une closure est le dernier paramètre d'une fonction, vous pouvez la sortir des parenthèses pour plus de clarté.
let sortedNumbers = numbers.sorted { $0 < $1 }
Capturer les Valeurs dans une Closure
Les closures peuvent capturer et stocker des références aux variables et constantes de leur contexte environnant.
Exemple :
func makeIncrementer(incrementAmount: Int) -> () -> Int {
var total = 0
let incrementer: () -> Int = {
total += incrementAmount
return total
}
return incrementer
}
let incrementByTen = makeIncrementer(incrementAmount: 10)
print(incrementByTen()) // Affiche : 10
print(incrementByTen()) // Affiche : 20
Dans cet exemple :
- La fonction
makeIncrementerretourne une closure qui capture la variabletotal. - Chaque fois que la closure est appelée, elle modifie et utilise la valeur de
total, même si elle n'est plus dans la portée de la fonction d'origine.