#Les closures

Vous allez en voir de partout en Swift, alors il faut savoir les lire, et si vous savez les utiliser, c’est encore mieux !

Les closures sont un concept puissant en Swift.

🧠 Les closures sont des blocs de code autonomes qui peuvent être assignés à des variables, passés en tant qu’arguments de fonction, ou retournés comme valeurs de fonction. Elles capturent et stockent des références aux variables et aux constantes de leur contexte entourant, ce qui les rend auto-contenues et indépendantes.

🛟 Mémo sur les syntaxes : https://fuckingclosuresyntax.com/

#Syntaxe de base

La syntaxe de base d’une closure ressemble à ceci :

swift
let closureName: (parameters) -> returnType = {
    // Code de la closure
    // Elle peut référencer des variables extérieures
}

Exemple :

swift
let greet = {
    print("Hello!")
}

// Appel de la closure
greet()  // Affiche "Hello!"

#Utilisation de paramètres

Les closures peuvent prendre des paramètres et retourner des valeurs :

swift
let add = { (a: Int, b: Int) -> Int in
    return a + b
}

let result = add(3, 5)  // result est égal à 8

#Capturer des variables extérieures

Les closures peuvent capturer et stocker des références aux variables et constantes de leur contexte entourant. C’est ce qu’on appelle “capturer les valeurs” et cela rend les closures auto-contenues.

swift
func makeIncrementer(incrementAmount: Int) -> () -> Int {
    var total = 0
    
    let incrementer: () -> Int = {
        total += incrementAmount
        return total
    }
    
    return incrementer
}

let incrementByTwo = makeIncrementer(incrementAmount: 2)
print(incrementByTwo())  // Affiche 2
print(incrementByTwo())  // Affiche 4

#Closures en tant qu’arguments de fonction

Les closures peuvent être passées en tant qu’arguments de fonction. Cela est souvent utilisé pour fournir une fonction personnalisée ou un comportement lors de l’appel de la fonction.

swift
func operateOnNumbers(a: Int, b: Int, operation: (Int, Int) -> Int) -> Int {
    return operation(a, b)
}

let addClosure = { (a: Int, b: Int) -> Int in
    return a + b
}

let result = operateOnNumbers(a: 5, b: 3, operation: addClosure)  // result est égal à 8

#Échappement et non-échappement

En Swift, les closures sont par défaut non-échappantes, ce qui signifie qu’elles sont exécutées immédiatement. Pour permettre à une closure de survivre après la fin de la fonction où elle est déclarée, elle doit être annotée avec @escaping.

swift
var completionHandlers: [() -> Void] = []

func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

#Autres concepts

  • Trailing Closures : Si la dernière expression d’une fonction est une closure, vous pouvez la déplacer en dehors des parenthèses.

    swift
    someFunctionWithClosure {
        // code de la closure
    }
    
  • Closures Shorthand Syntax : Swift offre une syntaxe concise pour les closures, particulièrement lorsque la closure est utilisée comme dernière argument d’une fonction.

    swift
    let names = ["Alice", "Bob", "Charlie"]
    let sortedNames = names.sorted { $0 < $1 }
    

Les closures sont un aspect puissant de Swift, et leur compréhension est essentielle pour de nombreux aspects du développement iOS en Swift.

Les closures sont fréquemment utilisées dans des API telles que les animations, les gestionnaires de complétion, et les fonctions de traitement de collections.

La documentation Swift sur les closures fournit des informations détaillées et des exemples supplémentaires.