Closure
Closure
Une closure, c’est un morceau de code que tu peux écrire directement et utiliser facilement dans ton programme. C’est un peu comme une mini-fonction, mais en plus flexible.
La grande différence avec une fonction, c’est que la closure peut se souvenir de ce qui se passe autour d’elle, comme des variables ou des constantes définies juste avant. Tu peux l’écrire, la garder dans une variable, et même la passer à une autre fonction pour dire : “Fais ça avec ce morceau de code”.
Pourquoi apprendre les closures ?
→ Elles te permettent d’écrire du code plus compact et plus lisible.
→ Elles sont parfaites pour faire des choses répétitives ou sur-mesure, comme trier une liste ou définir des actions à réaliser plus tard.
→ Tu vas les croiser partout dans Swift UI, alors mieux vaut bien comprendre les bases !
Les closures peuvent sembler abstraites au départ, donc le but de ce cours est de démystifier la notion en montrant qu’elles ne sont qu’une manière différente d’écrire et de manipuler du code. Voici une progression claire pour les rendre compréhensibles et utiles.
Comparaison avec une func
Sur le papier, une fonction et une closure se ressemblent beaucoup. La principale différence est que la closure n’a pas de nom. Si on regarde leur syntaxe, elles peuvent toutes les deux :
→ Prendre des paramètres (typés).
→ Retourner un type.
Voici une comparaison claire pour que tu voies la similitude :
func add(a: Int, b: Int) -> Int {
return a + b
}
let result = add(a: 3, b: 4)
print(result)
// Lecture dans la console -> 7
→ Paramètres a: Int et b: Int (deux nombres entiers).
→ Retour Int (le résultat est un nombre entier).
let addClosure: (Int, Int) -> Int = { (a: Int, b: Int) in
return a + b
}
let result = addClosure(3, 4)
print(result)
// Lecture dans la console -> 7
→ Paramètres (a: Int, b: Int) (comme la fonction).
→ Retour Int (le type du résultat est aussi précisé).
Ce qu’il faut retenir, c’est qu’une fonction a un nom (ici, add) et qu’elle est définie par un mot-clé (func), tandis que la closure n’a pas de nom et est souvent assignée à une variable ou utilisée directement.
Jusque-là, c’est très simple. C’est ce qu’on appelle une fonction anonyme dans d’autres langages. Ça te permet d’avoir un bloc de code à la volée, sans avoir à définir une fonction. Maintenant, on va continuer à approfondir l’apprentissage des closures avec ce qui fait leur puissance : leur capacité à capturer le contexte externe.
Capturer le contexte externe
var counter = 0
let increment = {
counter += 1
print("Compteur : \(counter)")
}
increment()
increment()
// Lecture dans la console -> Compteur : 1
// Lecture dans la console -> Compteur : 2
Capturer le contexte, ça veut simplement dire que la closure pourra lire les données externes à elle-même. Ici, elle peut lire et travailler sur la variable counter, ce qui n’est pas possible avec une fonction.
Closures en tant que paramètres de fonction
func goTask(action: () -> Void) {
print("Début de la tâche.")
action()
print("Fin de la tâche.")
}
goTask{
print("Faire la vaisselle...")
}
/*
Lecture dans la console ->
Début de la tâche.
Faire la vaisselle...
Fin de la tâche.
*/
La fonction goTask() accepte une closure comme paramètre, spécifiée par action: () -> Void. (En Swift, Void signifie que la closure n’a ni retour, ni valeur à fournir.)
Cette approche rend la fonction beaucoup plus flexible, tu peux adapter son comportement en lui passant la logique que tu veux exécuter au moment de son utilisation.
func goTask(action: () -> Void) {
print("Début de la tâche.")
action()
print("Fin de la tâche.")
}
var number = 2
goTask {
number += 1
print(number)
}
/*
Lecture dans la console ->
Début de la tâche.
3
Fin de la tâche.
*/
Simplifications des closures
//Avant
let addClosure: (Int, Int) -> Int = { (a: Int, b: Int) in
return a + b
}
//Après
let addClosure = { (a, b) in a + b }
Swift supprime les éléments redondants grâce à sa capacité à deviner les types. Le type (Int, Int) -> Int est automatiquement déduit en fonction de l’utilisation ou du contexte. De plus, comme le corps de la closure ne contient qu’une seule ligne, le mot-clé return est omis, car Swift comprend automatiquement que cette ligne est la valeur retournée.
let addClosure = { $0 + $1 }
La closure devient ultra compacte grâce à l’utilisation des paramètres automatiques ($0, $1, etc.).
→ $0 Représente le premier paramètre de la closure.
→ $1 Représente le deuxième paramètre de la closure.
Avec cette syntaxe, il n’est plus nécessaire de nommer les paramètres (a, b) ou de spécifier leur type, car Swift devine tout automatiquement à partir du contexte.
Closures et Fonctions de Haute-Ordre
Les closures sont couramment utilisées avec les fonctions de haute-ordre, qui sont des fonctions qui prennent des fonctions (ou des closures) en paramètres ou qui retournent des fonctions (ou des closures).
Explication de la Syntaxe $0 dans les Fonctions de Haute-Ordre
Lorsque tu utilise des fonctions de haute-ordre comme map, filter et reduce , tu peux utiliser la syntaxe abrégée pour référencer les paramètres des closures. Cette syntaxe utilise des symboles comme $0, $1, etc., pour représenter les arguments de la closure. Cette notation permet de rendre le code plus concis et lisible.
let names = ["Harry", "Hermione", "Ron"]
let uppercasedNames = names.map { $0.uppercased()}
print(uppercasedNames)
Lecture dans la console ->
["HARRY", "HERMIONE", "RON"]
filter
let numbers = [1, 2, 3, 4, 5, 6]
let evenNumbers = numbers.filter { $0 % 2 == 0 }
print(evenNumbers)
Lecture dans la console ->
[2, 4, 6]
reduce
let scores = [10, 20, 30, 40]
let totalScore = scores.reduce(0) { $0 + $1 }
print(totalScore)
Lecture dans la console ->
100
Exercices Pratiques
Exo closure
Télécharger le playground
Accède aux consignes directement en téléchargeant le playground.
⚠️ Les consignes que tu trouveras dans le playground ne sont pas verrouillées. Fais attention à ne pas les effacer par inadvertance !
Objectif
Les closures en Swift sont un outil puissant et essentiel pour écrire un code concis, flexible et réutilisable. Elles te permettent de capturer le contexte environnant, de personnaliser le comportement des fonctions, et de simplifier des tâches répétitives. Comprendre les closures te donnera les clés pour tirer pleinement parti de nombreuses fonctionnalités de Swift, comme les collections, les tâches asynchrones, et les interactions dynamiques. Avec les closures, tu pourras rendre ton code plus modulaire, clair, et adaptable aux besoins de ton application. Apprendre à les maîtriser, c’est poser une base solide pour écrire du code Swift moderne et performant.
Quiz
Après un peu de pratique, il est temps de te tester avec un petit quiz pour vérifier si tout est clair pour toi. Prends ton temps, lis bien les questions, et bonne chance..
Note
Les paramètres automatiques comme $0, $1 sont pratiques pour les closures simples, mais dans les cas complexes, il est préférable de nommer les paramètres pour améliorer la lisibilité.
Exercices Pratiques
Exo closure
Télécharger le playground
Accède aux consignes directement en téléchargeant le playground.
⚠️ Les consignes que tu trouveras dans le playground ne sont pas verrouillées. Fais attention à ne pas les effacer par inadvertance !
Objectif
Les closures en Swift sont un outil puissant et essentiel pour écrire un code concis, flexible et réutilisable. Elles te permettent de capturer le contexte environnant, de personnaliser le comportement des fonctions, et de simplifier des tâches répétitives. Comprendre les closures te donnera les clés pour tirer pleinement parti de nombreuses fonctionnalités de Swift, comme les collections, les tâches asynchrones, et les interactions dynamiques. Avec les closures, tu pourras rendre ton code plus modulaire, clair, et adaptable aux besoins de ton application. Apprendre à les maîtriser, c’est poser une base solide pour écrire du code Swift moderne et performant.
Quiz
Après un peu de pratique, il est temps de te tester avec un petit quiz pour vérifier si tout est clair pour toi. Prends ton temps, lis bien les questions, et bonne chance..
Note
Les paramètres automatiques comme $0, $1 sont pratiques pour les closures simples, mais dans les cas complexes, il est préférable de nommer les paramètres pour améliorer la lisibilité.