ProgrammationDéveloppeur mobile

Comment fonctionnent switch/enum en Swift, quelles sont leurs caractéristiques et en quoi diffèrent-ils des analogues dans d'autres langages ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Dans Swift, les constructions switch et enum sont dotées de puissantes capacités de correspondance de motifs et d'une sécurité de type stricte, ce qui les distingue de la plupart des analogues dans d'autres langages.

Historique de la question

Dans C et C++, ainsi que dans Objective-C, les énumérations ne représentent qu'un ensemble de valeurs entières, et les opérateurs switch comparent les valeurs par correspondance. En Swift, les énumérations (enum) sont beaucoup plus puissantes — elles prennent en charge des valeurs associées, des propriétés calculées et des méthodes. L'opérateur switch prend en charge la correspondance de motifs, la protection contre les branches incomplètes et fonctionne avec des plages, des tuples, des optionnels et beaucoup d'autres choses.

Problème

Dans les langages traditionnels, switch conduit souvent à des erreurs liées à l'absence d'exhaustivité (c'est-à-dire la prise en compte de tous les cas), des erreurs de type et l'incapacité de stocker en toute sécurité des données supplémentaires dans les cas d'énumération. Cela entraîne des erreurs à l'exécution plutôt qu'à la compilation.

Solution

Dans Swift, switch exige un traitement complet de tous les cas, sauf si l'énumération est explicitement marquée comme @unknown default. Les valeurs associées permettent de stocker élégamment des informations supplémentaires dans les cas d'énumération. Exemple :

enum NetworkResult { case success(Int) case failure(String) } func handle(result: NetworkResult) { switch result { case .success(let code): print("Succès avec code: \(code)") case .failure(let error): print("Échec avec erreur: \(error)") } }

Caractéristiques clés :

  • Les énumérations enum peuvent avoir des valeurs/données associées
  • Le mécanisme switch exige une couverture complète de tous les cas (correspondance exhaustive)
  • Swift prend en charge la correspondance de motifs pour les tuples, les plages, les optionnels, et pas seulement pour les enum

Questions pièges.

Faut-il toujours écrire default dans switch pour les enum ?

Non, si tous les cas de l'énumération sont explicitement couverts, default n'est pas nécessaire. De plus, il n'est pas recommandé d'utiliser default sauf si nécessaire — le compilateur peut ne pas avertir de nouveaux cas d'énumération lors de leur ajout.

Peut-on utiliser fallthrough pour un passage automatique entre les cas ?

Oui, le mot clé fallthrough est disponible, mais il faut l'utiliser avec prudence. Il ne passe pas les valeurs associées, et de tels passages sont rares dans la pratique réelle de Swift.

switch number { case 1: print("un") fallthrough case 2: print("ou deux") default: print("autres") }

Un enum en Swift peut-il être comparé par rawValue s'il a des valeurs associées ?

Non. Seules les énumérations sans valeurs associées et avec un rawValue explicitement spécifié peuvent être initialisées et comparées via rawValue.

Erreurs typiques et anti-patrons

  • Ajouter default dans switch pour les enum "par sécurité" — cela cache l'apparition de nouveaux cas
  • Utiliser des enums avec un grand nombre de cas pour stocker des données complexes, alors qu'il vaudrait mieux utiliser une structure
  • Ne pas utiliser la correspondance de motifs et ignorer les valeurs associées

Exemple de la vie réelle

Cas négatif

Un développeur a ajouté un cas default dans switch pour l'énumération NetworkResult, ce qui a conduit à ce qu'à l'ajout d'un nouveau cas, la logique de traitement ne soit pas mise à jour, et le programme fonctionnait "silencieusement" de manière incorrecte.

Avantages : Pas d'avertissements du compilateur lors de l'ajout de cas.

Inconvénients : Les erreurs se manifestent pendant l'exécution de l'application, la logique ne se met pas à jour automatiquement.

Cas positif

Un employé a refusé le default dans switch pour les enum, ce qui a permis au compilateur de détecter l'absence de traitement des nouveaux cas après leur ajout.

Avantages : Les erreurs sont détectées au moment de la compilation, le comportement de l'application devient plus prévisible.

Inconvénients : Avec un grand nombre de cas, plus de code est nécessaire, mais cela apporte de la fiabilité.