Historique de la question :
Les types opaques (some) ont été introduits avec Swift 5.1 et ouvrent une nouvelle façon d'abstraire le type de retour d'une fonction ou d'une propriété, lorsque le type est connu du compilateur mais caché à l'utilisateur. C'est une alternative aux existentials de protocole (any Protocol), mais avec une liaison stricte à un type spécifique à l'intérieur de la fonction.
Problème : Lorsque la fonction retourne un protocole avec un associatedtype (par exemple, Sequence), on ne peut pas écrire directement :
func makeNumberSequence() -> Sequence { ... } // erreur
Les existentials de protocole permettent de retourner n'importe quelle implémentation, mais ne garantissent pas le même type à chaque appel :
func foo() -> any View { ... }
Cela mène à de l'imprévisibilité et à une faible sécurité de type.
Solution : Utiliser le type de résultat opaque :
func makeNumbers() -> some Sequence { [1, 2, 3] }
Maintenant, le compilateur connaît exactement le type de retour, mais il est caché à l'extérieur. Cela permet des optimisations de performance, une sécurité accrue, facilite l'utilisation du DSL SwiftUI et aide à l'échange de types entre les modules.
Caractéristiques clés :
Les types opaques peuvent-ils être utilisés pour stocker des valeurs (comme des propriétés de classe) ?
Non. Les types opaques ne s'appliquent qu'aux valeurs de retour des fonctions ou des propriétés calculées. Pour stocker une valeur ou un tableau de valeurs, on utilise les existentials (any Protocol).
Les différentes branches d'une même fonction peuvent-elles retourner différents types avec some ?
Non. Le compilateur exige que toutes les branches retournent le même type concret, sinon une erreur se produira :
func foo(flag: Bool) -> some Sequence { if flag { return [1, 2, 3] } else { return ["a", "b", "c"] // erreur } }
Peut-on utiliser some pour identifier le type de retour entre plusieurs fonctions ?
Non. Chaque fonction avec some retourne son propre type caché unique, même si en réalité c'est le même tableau. Utiliser le résultat d'une fonction comme paramètre dans une autre n'est pas possible si les deux utilisent some avec différents protocoles ou différents types cachés.
Dans un projet, tout est retourné via any Protocol, les collections perdent leur typage, des bugs apparaissent lors du downcast, ce qui ralentit l'optimisation compile-time.
Avantages :
Inconvénients :
Dans la conception SwiftUI, les composants retournent some View, chaque module définit clairement son type interne. La taille du bundle est réduite, la compilation est accélérée.
Avantages :
Inconvénients :