Le mot-clé `some` en Swift et SwiftUI : à quoi sert-il ?

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

Le mystérieux « some » : pourquoi des milliers de développeurs s’interrogent-ils à son sujet ?

\n\n

Si vous avez déjà écrit du code en SwiftUI, vous avez sûrement vu la construction some View. Elle semble simple, mais les débutants sont souvent perdus : « Qu’est-ce que ce « some » ? Pourquoi ne peut-on pas simplement écrire View ? Et si j’enlève some, est-ce que ça casse ? ». La question « What is the "some" keyword in Swift(UI)? » a recueilli des milliers de vues sur Stack Overflow – et ce n’est pas un hasard. Derrière un mot court se cache toute une philosophie du Swift moderne.

\n\n

Dans cet article, nous allons comprendre ce qu’est le mot-clé some, pourquoi il est apparu dans le langage et pourquoi il est impossible d’imaginer SwiftUI sans lui. Vous découvrirez comment il est lié aux génériques, aux protocoles et aux « types opaques » (opaque types). Et surtout, vous comprendrez comment écrire un code plus propre et plus performant.

\n\n

Le problème que résout « some »

\n\n

Imaginez que vous écrivez une fonction qui retourne un objet conforme au protocole View. En SwiftUI, cela arrive constamment :

\n\n
func makeGreeting() -> View {\n    return Text("Hello!")\n}
\n\n

Le compilateur Swift vous dira : « Le protocole 'View' ne peut être utilisé que comme une contrainte générique (generic constraint), car il a des exigences Self ou associated type ». Cela semble effrayant, mais le principe est simple : le protocole View dans SwiftUI exige que le type soit connu à la compilation. Si nous retournons View – c’est une abstraction, alors que le compilateur a besoin de concret.

\n\n

Avant, les développeurs se débrouillaient avec des génériques :

\n\n
func makeGreeting<T: View>() -> T {\n    return Text("Hello!") as! T\n}
\n\n

Cela fonctionnait, mais ressemblait à une rustine : vous promettez au compilateur de retourner T, mais en réalité vous « faites semblant ». De plus, le code appelant devait explicitement spécifier le type. Pas joli et pas sûr.

\n\n

« Some » – le sauveur du code passe-partout

\n\n

Le mot-clé some en Swift est apparu dans la version 5.1 précisément pour ces cas. Il dit au compilateur : « Je vais retourner un type concret qui se conforme au protocole, mais je ne veux pas donner son nom. Tu le détermines toi-même à la compilation ». C’est ce qu’on appelle un type opaque (opaque type).

\n\n

Revenons à notre exemple :

\n\n
func makeGreeting() -> some View {\n    return Text("Hello!")\n}
\n\n

Maintenant, le code se compile ! Le compilateur sait que c’est précisément Text qui est retourné, mais de l’extérieur, nous voyons seulement some View. Cela apporte deux choses :

\n
    \n
  • Sécurité des types – le compilateur vérifie que le type retourné est toujours le même.
  • \n
  • Encapsulation – nous cachons les détails d’implémentation au code appelant.
  • \n
\n\n

Comparaison : « some » vs génériques vs protocoles

\n\n

Pour mieux comprendre la magie de some, comparons les trois approches sur un exemple concret. Supposons que nous voulions écrire une fonction qui retourne une forme (cercle ou carré).

\n\n

1. Retour d’un protocole (ne se compile pas)

\n\n
protocol Shape {\n    func draw()\n}\n\nstruct Circle: Shape {\n    func draw() { print("Dessiner un cercle") }\n}\nstruct Square: Shape {\n    func draw() { print("Dessiner un carré") }\n}\n\n// Erreur : le protocole 'Shape' ne peut pas être utilisé comme type de retour\nfunc makeShape() -> Shape {\n    return Circle()\n}
\n\n

Comme nous le savons déjà – cela ne fonctionne pas si le protocole a des associated types ou des exigences Self.

\n\n

2. Utilisation de génériques

\n\n
func makeShape<T: Shape>() -> T {\n    // Il faut créer T d’une manière ou d’une autre, mais nous ne connaissons pas le type concret\n    fatalError("Impossible de créer un générique")\n}
\n\n

Problème : le code appelant doit savoir quel type attendre. La fonction ne peut pas décider elle-même quoi retourner.

\n\n

3. Utilisation de « some » (fonctionne parfaitement)

\n\n
func makeShape() -> some Shape {\n                

Blogs

Book Recommendations