ProgrammationSenior iOS Developer

Décrivez le mécanisme des generics en Swift. Comment assurer la sécurité de type lors de l'utilisation de types génériques ? Donnez des exemples de restrictions sur les types génériques.

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Les generics (types génériques) permettent de définir des fonctions et des types flexibles et réutilisables. La caractéristique clé de Swift est le maintien de la sécurité de type : le compilateur vérifie l'utilisation de types spécifiques lors de la compilation. Les types génériques peuvent être restreints par des conditions where, l'héritage de protocoles et leur combinaison.

Exemple de code :

func swapValues<T>(_ a: inout T, _ b: inout T) { let temp = a a = b b = temp } protocol Drawable { func draw() } func drawAll<T: Drawable>(_ items: [T]) { for item in items { item.draw() } } // Restriction par protocole et condition where func compareValues<T: Equatable>(_ a: T, _ b: T) -> Bool { return a == b }

Question piège.

Les fonctions génériques peuvent-elles être surchargées avec des fonctions ordinaires ? Comment le compilateur choisit-il la bonne implémentation ?

Réponse : Oui, les fonctions génériques peuvent être surchargées avec des fonctions ordinaires et d'autres fonctions génériques. Le compilateur essaie de choisir l'implémentation la plus spécifique. Exemple :

func printValue(_ value: Int) { print("Int: \(value)") } func printValue<T>(_ value: T) { print("Générique: \(value)") } printValue(5) // Int: 5 printValue("Swift") // Générique: Swift

Exemples d'erreurs réelles dues à une méconnaissance des subtilités du sujet.


Histoire

L'équipe a écrit une extension générique de tableau pour rechercher un indice, en oubliant de restreindre le type via Equatable. Cela a conduit à une erreur de compilation lors de la tentative d'application de l'extension sur un tableau avec des éléments non Equatable.


Histoire

Dans le projet, ils ont essayé de réaliser un cache pour des objets génériques sans restriction de type. En conséquence, lors de la tentative de downcast à l'exécution, des crashs se produisaient — une utilisation réellement sécurisée aurait pu être atteinte par des protocoles avec des types associés et des contraintes.


Histoire

Les développeurs ont mis en œuvre une classe générique, mais lors de l'héritage et de la redéfinition, ils ont oublié la nécessité d'indiquer le paramètre générique complet de l'héritier. En raison de cela, le code ne compilait pas et une refonte complète de la hiérarchie des types était nécessaire.