Les extensions dans Swift peuvent :

  • Ajouter des propriétés calculées et des propriétés de types calculés
  • Définir des méthodes d'instances et des méthodes de types
  • Fournir de nouveaux initialiseurs
  • Définir des indices
  • Définir et utiliser de nouveaux types imbriqués
  • Rendre un type existant conforme à un protocole

Quand utiliser les extensions Swift :

  • Fonctionnalité supplémentaire à Swift
  • Fonctionnalité supplémentaire pour UIKit / Foundation
  • Fonctionnalité supplémentaire sans déranger le code des autres personnes
  • Classes de décomposition en: Données / Fonctionnalité / Délégué

Quand ne pas utiliser :

  • Étendre vos propres classes à partir d'un autre fichier

Déclarer une extension

Déclarez les extensions avec le mot clé extension :


extension Int {
    // new functionality to add to Int goes here
}

Ajouter une propriété calculée

Les extensions peuvent ajouter des propriétés d'instances calculées et des propriétés de types calculés aux types existants.


extension Double {
    var km: Double { return self * 1_000.0 }
    var m: Double { return self }
    var cm: Double { return self / 100.0 }
    var mm: Double { return self / 1_000.0 }
    var ft: Double { return self / 3.28084 }
}
let oneInch = 25.4.mm
print("One inch is \(oneInch) meters")
// Prints "One inch is 0.0254 meters"
let threeFeet = 3.ft
print("Three feet is \(threeFeet) meters")
// Prints "Three feet is 0.914399970739201 meters"

Ajouter un initialiseur

Cela vous permet d'étendre d'autres types pour accepter vos propres types personnalisés comme paramètres d'initialisations ou de fournir des options d'initialisations supplémentaires qui n'étaient pas incluses dans l'implémentation d'origine du type.

Les extensions peuvent ajouter de nouveaux initialiseurs pratiques à une classe, mais elles ne peuvent pas ajouter de nouveaux initialiseurs ou désinitialiseurs désignés à une classe. Les initialiseurs et désinitialiseurs désignés doivent toujours être fournis par l'implémentation de classe d'origine.

Ajouter une méthode


extension Int {
    func repetitions(task: () -> Void) {
        for _ in 0..<self {
            task()
        }
    }
}

3.repetitions {
    print("Hello!")
}
// Hello!
// Hello!
// Hello!

Instance en mutation

Les méthodes d'instances ajoutées avec une extension peuvent également modifier (ou muter) l'instance elle-même. Les méthodes de structure et d'énumération qui modifient self ou ses propriétés doivent marquer la méthode d'instance comme mutating, tout comme les méthodes de mutation d'une implémentation d'origine.


extension Int {
    mutating func square() {
        self = self * self
    }
}
var someInt = 3
someInt.square()
// someInt is now 9

Ajouter un indice


extension Int {
    subscript(digitIndex: Int) -> Int {
        var decimalBase = 1
        for _ in 0..<digitIndex {
            decimalBase *= 10
        }
        return (self / decimalBase) % 10
    }
}
746381295[0]  // returns 5
746381295[1]  // returns 9
746381295[2]  // returns 2
746381295[8]  // returns 7

Ajouter un type imbriqué


extension Int {
    enum Kind {
        case negative, zero, positive
    }
    var kind: Kind {
        switch self {
        case 0:
            return .zeros
        case let x where x > 0:
            return .positive
        default:
            return .negative
        }
    }
}