Les Extensions en Swift

Introduction aux Extensions

Les extensions en Swift offrent la flexibilité d'ajouter de nouvelles fonctionnalités aux types de données existants sans avoir à toucher à leur code original. Grâce à ces extensions, il est possible d'implémenter des méthodes, des propriétés calculées, ainsi que de nouveaux initialisateurs. En outre, une extension peut permettre à un type donné de se conformer à un protocole.

Syntaxe des Extensions

Pour définir une extension, il suffit d'utiliser le mot clé extension. Voici un exemple de syntaxe :

extension SomeExistingType {
    // Ajoutez ici vos nouvelles fonctionnalités
}

Pour rendre un type existant conforme à un protocole, la syntaxe est la suivante :

extension SomeExistingType: AProtocol, AnotherProtocol {
    // Implémentez ici les exigences du protocole
}

Il est à noter qu'une extension ne peut pas ajouter de nouvelles propriétés stockées ni remplacer des méthodes existantes. Cependant, un même type peut être étendu plusieurs fois, comme le montre l'exemple suivant :

extension SameType: Protocol {
    // Implémentation du protocole
}

extension SameType: AnotherProtocol {
    // Implémentation de l'autre protocole
}

extension SameType {
    // Ajoutez ici de nouvelles méthodes et propriétés calculées
}

extension SameType {
    // Ajoutez ici d'autres méthodes
}

En divisant les extensions par catégories de fonctionnalités, vous améliorez la lisibilité et la maintenabilité du code.

Propriétés Calculées

Les extensions peuvent être utilisées pour enrichir le type Int avec des fonctionnalités supplémentaires. Par exemple, ajoutons deux propriétés calculées permettant de calculer le carré et le cube d'un entier :

extension Int {
    var squared: Int { return self * self }
    var cubed: Int { return self * self * self }
}

L'utilisation de ces propriétés peut se faire ainsi :

print("Le carré de 2 est \(2.squared).")  // Affiche : "Le carré de 2 est 4."
print("Le cube de 3 est \(3.cubed).")      // Affiche : "Le cube de 3 est 27."

Une autre utilisation fréquente d'extensions est d'améliorer l'affichage d'un type. Par exemple, en rendant une structure conforme au protocole CustomStringConvertible :

struct Person {
    let name: String
    let age: Int
}

let person = Person(name: "Bob", age: 35)
print(person)  // Affiche: Person(name: "Bob", age: 35)

extension Person: CustomStringConvertible {
    var description: String {
        return "Salut, je m'appelle \(name) et j'ai \(age) ans."
    }
}

print(person) // Affiche: "Salut, je m'appelle Bob et j'ai 35 ans."

Méthodes

Les extensions permettent aussi d'ajouter de nouvelles méthodes d'instance et des méthodes de type. Prenons le type Int et ajoutons-y une méthode qui retourne un message personnalisé, ainsi qu'une méthode qui modifie l'instance :

extension Int {
    func sayNumber() -> String {
        return "Je suis le nombre \(self)."
    }
    mutating func squared() {
        self = self * self
    }
}

var x = 4
print(x.sayNumber()) // Affiche: "Je suis le nombre 4."

x.squared()
print(x) // Affiche: 16