Generics et typage en Swift : comment écrire du code qui travaille pour vous

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Pourquoi sans génériques votre code Swift se transformera bientôt en spaghetti

\n\n

Imaginez que vous écrivez une application de livraison de pizzas. Vous devez traiter les commandes, les clients, les livreurs — et à chaque fois écrire le même code pour le tri, la recherche ou le filtrage, en changeant uniquement le type de données ? Cela ressemble au cauchemar de tout développeur. C'est ici qu'entrent en scène les Generics en Swift — un outil puissant qui permet d'écrire un code flexible et réutilisable sans sacrifier la sécurité des types.

\n\n

Dans cet article, nous ne nous contenterons pas de survoler la syntaxe. Nous analyserons comment le typage en Swift et les génériques fonctionnent ensemble pour que votre code soit non seulement beau, mais aussi fiable. Vous apprendrez à vous débarrasser du copier-coller, à utiliser protocol avec associatedtype et pourquoi les clauses where sont vos meilleures amies.

\n\n

Que sont les Generics et pourquoi changent-ils les règles du jeu

\n\n

Les Generics (génériques, types génériques) sont un mécanisme qui permet d'écrire des fonctions, structures, classes et énumérations qui fonctionnent avec n'importe quel type de données satisfaisant certaines conditions. Au lieu d'écrire trois versions d'une fonction pour Int, String et Double, vous en écrivez une qui fonctionne avec n'importe quel type.

\n\n

En Swift, le typage est strict et statique. Cela signifie que le compilateur vérifie les types au moment de la compilation. Les Generics ne violent pas cette règle — ils la rendent plus flexible. Le compilateur déduit lui-même le type concret lors de l'appel de la fonction, mais les vérifications restent.

\n\n

Premier exemple : fonction sans génériques

\n\n
// Mauvais : trois fonctions pour trois types\nfunc swapInts(_ a: inout Int, _ b: inout Int) {\n    let temp = a\n    a = b\n    b = temp\n}\n\nfunc swapStrings(_ a: inout String, _ b: inout String) {\n    let temp = a\n    a = b\n    b = temp\n}\n\nfunc swapDoubles(_ a: inout Double, _ b: inout Double) {\n    let temp = a\n    a = b\n    b = temp\n}
\n\n

Et maintenant — une solution élégante avec des génériques :

\n\n
// Bien : une fonction pour tous les types\nfunc swapValues<T>(_ a: inout T, _ b: inout T) {\n    let temp = a\n    a = b\n    b = temp\n}\n\n// Utilisation :\nvar x = 10\nvar y = 20\nswapValues(&x, &y) // T = Int\n\nvar name1 = "Alice"\nvar name2 = "Bob"\nswapValues(&name1, &name2) // T = String
\n\n

Vous voyez la magie ? <T> est un placeholder (espace réservé) de type. Le compilateur substitue lui-même le type réel lors de l'appel. C'est la base de la programmation générique en Swift.

\n\n

Types génériques : créons notre propre pile universelle

\n\n

Les génériques en Swift fonctionnent non seulement avec les fonctions, mais aussi avec des types entiers. Créons une structure Stack — un exemple classique de structure de données LIFO (Last In, First Out).

\n\n
struct Stack<Element> {\n    private var items: [Element] = []\n    \n    mutating func push(_ item: Element) {\n        items.append(item)\n    }\n    \n    mutating func pop() -> Element? {\n        return items.popLast()\n    }\n    \n    func peek() -> Element? {\n        return items.last\n    }\n    \n    var count: Int {\n        return items.count\n    }\n}\n\n// Utilisation :\nvar intStack = Stack<Int>()\nintStack.push(1)\nintStack.push(2)\nintStack.push(3)\nprint(intStack.pop() ?? 0) // 3\n\nvar stringStack = Stack<String>()\nstringStack.push("Swift")\nstringStack.push("Generics")\nprint(stringStack.peek() ?? "") // "Generics"
\n\n

Remarquez : le type Element est spécifié entre chevrons lors de la déclaration de la structure. Lors de la création d'une instance, nous le concrétisons — Stack<Int> ou Stack<String>. Le compilateur garantit que vous ne pouvez pas accidentellement mettre une chaîne dans une pile d'entiers.

\n\n

Protocol avec associatedtype : génériques pour les protocoles

\n\n

En Swift, les protocoles ne peuvent pas avoir de paramètres génériques directement. À la place, on utilise

Blogs

Book Recommendations