Opaque Type : ce que c’est, some et any en Swift

Auteur : IT Sectr Publié le : 2026-06-18 Temps de lecture : 11 min

Opaque Type est un mécanisme de Swift qui permet à une fonction de retourner une valeur d’un certain type sans révéler le type concret au code appelant. Le mot-clé some dans le type de retour est l’exemple le plus célèbre : some View dans SwiftUI signifie « la fonction retourne un type qui se conforme à View, mais lequel exactement est un détail d’implémentation ». Un opaque type préserve l’identité du type (contrairement à un protocole en tant que type), ce qui permet au compilateur d’optimiser le code et garantit la cohérence du type retourné. Selon Swift Book, 2025, les opaque types résolvent le problème des protocoles avec types associés, permettant de retourner des valeurs de ces protocoles depuis des fonctions.

Points clés

  • Opaque Type — un type de retour qui masque l’implémentation concrète du code appelant
  • some — le mot-clé pour déclarer un opaque type en position de retour
  • Identité du type préservée : le compilateur connaît le type concret, contrairement à any
  • SwiftUI utilise some View comme méthode standard pour déclarer body
  • Limitation : une fonction avec some doit retourner le même type concret depuis toutes les branches

Qu’est-ce qu’un Opaque Type en Swift ?

Opaque Type est un type de retour déclaré avec le mot-clé some qui masque l’implémentation concrète du code appelant. L’appelant sait seulement que la valeur retournée est conforme à un protocole donné, mais ne sait pas exactement quel type se cache derrière some. Pendant ce temps, le compilateur connaît le type exact et l’utilise pour la distribution statique et l’optimisation.

Le problème que résout Opaque Type

Avant l’introduction des opaque types dans Swift 5.1 (SE-0244), il était impossible de retourner un protocole avec types associés depuis une fonction sans wrapper de boxing. Par exemple, le protocole Equatable a un type associé, et une fonction ne pouvait pas simplement retourner Equatable — le compilateur générait une erreur « le protocole ne peut être utilisé que comme contrainte générique ». Opaque type a résolu ce problème.

swift
func makeInt() -> some Equatable {
    return 42
}

func makeString() -> some Equatable {
    return "Hello"
}

// Le compilateur sait que makeInt retourne Int
// makeInt() == makeString() — ❌ erreur, types différents

Les deux fonctions retournent some Equatable, mais les types concrets sont différents : Int et String. Essayer de les comparer avec == provoquera une erreur de compilation car un opaque type garantit qu’un appel spécifique retourne le même type, mais pas entre différentes fonctions. C’est une fonctionnalité, pas un bug : opaque type préserve l’identité du type là où un protocole en tant que type (any Equatable) la perd.

Opaque Type vs Generic : quelle est la différence

Generic et Opaque Type sont les deux faces d’une même pièce. Les génériques permettent au code appelant de choisir le type, tandis que opaque type permet à la fonction de masquer le type au code appelant. La différence réside dans la direction du contrôle.

CaractéristiqueGeneric Opaque some
Qui choisit le typeCode appelantFonction/méthode
Identité du typePréservée (stable)Préservée (stable)
Nombre de branches de retourUne (via générique)Même type dans toutes les branches
UtilisationAlgorithmes, structures de donnéesSwiftUI, méthodes d’usine

Generic — choix externe

Dans une fonction générique, l’appelant décide quel type utiliser. La fonction doit fonctionner avec tout T satisfaisant les contraintes. Pour opaque type, l’appelant ne connaît pas le type concret — l’implémentation prend la décision.

swift
// Generic : l’appelant choisit le type
func identity<T>(_ value: T) -> T { value }
let x: Int = identity(42)

// Opaque : la fonction masque le type
func makeSomeEquatable() -> some Equatable { 42 }
let y = makeSomeEquatable()

Le choix entre generic et opaque type dépend de l’intention. Si le code appelant doit choisir le type, utilisez les génériques. Si la fonction doit masquer les détails d’implémentation, utilisez some. SwiftUI a choisi some View précisément parce que body doit être flexible en interne mais stable en externe.

Le mot-clé some et son utilisation

some est un mot-clé Swift introduit dans Swift 5.1 (SE-0244). Il est utilisé en position de retour pour déclarer un opaque type, ainsi que dans les paramètres (SE-0341) et les propriétés. some garantit que le type concret est stable et connu du compilateur mais masqué du code externe.

some dans les paramètres de fonction

À partir de Swift 5.7, some peut être utilisé non seulement en position de retour mais aussi dans les paramètres. some Equatable dans un paramètre signifie « cette fonction accepte tout type Equatable, mais tous les appels à l’intérieur d’un corps spécifique voient le même type ».

swift
func areEqual(_ a: some Equatable, _ b: some Equatable) -> Bool {
    // a et b — types potentiellement différents, == ne fonctionnera pas directement
    return isEqual(a, b)
}

func isEqual<T: Equatable>(_ a: T, _ b: T) -> Bool {
    return a == b
}

Utiliser some dans les paramètres offre une syntaxe plus concise par rapport à . C’est particulièrement utile dans les protocoles et la conception orientée protocole, où chaque utilisation d’un protocole ne nécessite pas un paramètre générique séparé. Le compilateur convertit en interne les paramètres some en génériques, donc les performances sont identiques.

Le mot-clé any et les types existentiels

any est un mot-clé Swift 5.6+ pour déclarer explicitement des types existentiels (protocole en tant que type). Contrairement à some, any efface l’identité du type : le compilateur ne sait pas quel type concret se cache derrière le protocole. Cela offre de la flexibilité (vous pouvez stocker différents types dans un même tableau), mais au prix des performances.

some vs any : analyse comparative

some — polymorphisme statique : le compilateur connaît le type concret, utilise la distribution directe et peut intégrer le code. any — polymorphisme dynamique : une table de méthodes virtuelles (conteneur existentiel) est utilisée, ce qui ajoute de l’indirection.

swift
protocol Drawable {
    func draw()
}

// some : le type statique est connu
func makeDrawable() -> some Drawable {
    return Circle() // Type de retour unique
}

// any : dynamique, peut stocker différents types
var shapes: [any Drawable] = [Circle(), Square()]
shapes.append(Triangle())

Le choix entre some et any est un compromis entre performances et flexibilité. Some est plus rapide mais se limite à une seule implémentation. Any est plus flexible (vous pouvez mélanger les types) mais plus lent en raison de la distribution dynamique. Dans SwiftUI, body utilise toujours some View car le body de chaque View est un type concret.

Opaque Type dans les protocoles avec types associés

Opaque Type résout un problème fondamental de Swift : les protocoles avec types associés (PAT) ne peuvent pas être utilisés directement comme type. Une fonction ne peut pas simplement retourner Collection — le compilateur exige de spécifier Element. some Collection résout cela en masquant le type associé.

Retourner PAT via some

Sans opaque type, retourner une Collection nécessiterait d’utiliser un type concret (Array) ou un effacement de type (AnyCollection). some Collection offre un juste milieu : le compilateur connaît l’implémentation concrète, le code appelant non.

swift
func makeReversedCollection<T>(
    of array: [T]
) -> some Collection {
    return array.reversed()
}

let result = makeReversedCollection(of: [1, 2, 3])
// result — ReversedCollection>, hidden from caller
for item in result {
    print(item)
}

result peut être itéré, mais vous ne pouvez pas accéder directement aux propriétés de ReversedCollection. Cela protège l’encapsulation : si vous remplacez plus tard reversed() par une autre méthode avec une implémentation différente, le code appelant ne sera pas cassé. Opaque type vous donne la liberté de modifier l’implémentation sans modifier l’API.

Exemples pratiques de some View dans SwiftUI

some View est l’utilisation la plus célèbre de opaque type. Chaque View dans SwiftUI déclare body comme some View. Cela signifie que body retourne un type concret de View, mais le développeur n’a pas besoin de réfléchir à ce que c’est exactement — TupleView, Group, ModifiedContent ou tout autre type du framework.

Comment SwiftUI utilise some View

Sans opaque type, body devrait retourner un type concret, par exemple ModifiedContent<Button<Text>, Padding>, ce qui est peu pratique. some View masque cette complexité. Le compilateur déduit le type exact de body automatiquement à la compilation.

swift
struct ContentView: View {
    var body: some View {
        VStack {
            Text("Bonjour")
                .font(.title)
            Button("Tapez-moi") {
                print("Tapé")
            }
        }
        .padding()
    }
}

Le compilateur déduit body comme ModifiedContent<VStack<TupleView<(Text, Button<Text>)>>, Padding>. Le développeur voit some View. Si vous changez la disposition de VStack en HStack, le compilateur re-déduira automatiquement le type — aucune modification manuelle nécessaire. C’est la magie d’opaque type : le développeur se concentre sur la logique de l’interface, pas sur les types de composition.

Questions fréquentes

Qu’est-ce qu’un Opaque Type en Swift ?

Opaque Type est un type déclaré avec le mot-clé some qui masque l’implémentation concrète du code appelant. Le compilateur connaît le type exact, mais le développeur utilisant la fonction ne voit que le protocole.

En quoi some diffère-t-il de any en Swift ?

some est un opaque type avec identité statique : le compilateur connaît le type concret. any est un type existentiel avec distribution dynamique : l’identité du type est effacée. Some est plus performant, any est plus flexible.

Pourquoi SwiftUI utilise-t-il some View ?

some View masque le type concret complexe de body, que le compilateur déduit automatiquement. Cela libère le développeur de la nécessité d’écrire le type exact composé de wrappers génériques (VStack, Group, ModifiedContent).

Peut-on utiliser some dans les paramètres de fonction ?

Oui, à partir de Swift 5.7. Some dans les paramètres est un sucre syntaxique sur un paramètre générique. Cela simplifie les déclarations de fonctions, surtout lors du travail avec des protocoles où chaque paramètre some ne nécessite pas de séparé.

Que se passe-t-il si on retourne différents types depuis une fonction some ?

Le compilateur générera une erreur : opaque type exige que toutes les branches de retour retournent le même type concret. C’est intentionnel pour préserver l’identité du type. Si vous devez retourner différents types, utilisez any.

Résumé

  • Opaque Type — masque le type concret de la valeur de retour tout en préservant son identité au niveau du compilateur
  • Le mot-clé some est utilisé pour déclarer un opaque type en position de retour et dans les paramètres
  • Generic vs Opaque : l’appelant choisit le type pour generic, l’implémentation choisit pour opaque
  • any — type existentiel avec distribution dynamique, some — polymorphisme statique
  • SwiftUI some View — le cas d’utilisation principal : masque le type complexe de body au développeur
  • Opaque type résout le problème de retour des protocoles avec types associés (PAT) depuis les fonctions

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi