Historique de la question :
Le shadowing (masquage) est un phénomène où une variable est déclarée avec le même nom dans une portée interne, masquant (cachant) la variable de la portée externe. Dans les anciennes versions de Swift, le compilateur était indulgent concernant le shadowing, mais avec la complexification du modèle de langage, l'identification explicite de tels cas est devenue nécessaire pour éviter les bogues.
Problème :
Le shadowing complique la maintenance du code et génère des erreurs difficiles à détecter — la déclaration accidentelle d'une variable avec le même nom peut entraîner un accès à une variable différente de celle que le développeur attend. C'est particulièrement critique dans les cas de passage de variables par référence et à l'intérieur de boucles ou de closures — souvent, les erreurs ne se manifestent qu'à l'exécution.
Solution :
Swift permet le shadowing des variables, mais il est recommandé d'éviter de masquer les variables/propriétés importantes, d'utiliser des noms différents ou d'appliquer des références explicites self/this. En particulier dans les initialisateurs de struct/class, il est recommandé d'utiliser self pour distinguer le membre et le paramètre :
Exemple de code :
struct User { let name: String init(name: String) { self.name = name // self garantit la clarté de l'affectation } }
Caractéristiques clés :
Que se passe-t-il lors du shadowing dans des boucles et des closures ?
Si vous déclarez une variable à l'intérieur d'une closure avec le même nom que dans le contexte externe, le shadowing cachera la variable externe. Cela peut parfois provoquer un comportement inattendu, surtout en multi-threading.
let value = 10 let closure = { let value = 20; print(value) } closure() // 20 print(value) // 10
Peut-on déclarer une constante et une variable avec le même nom dans la même portée ?
Non. Swift n'autorise pas d'avoir var et let pour le même nom dans la même portée :
let x = 5 var x = 10 // Erreur : Redéclaration invalide de 'x'
Comment éviter la confusion avec le shadowing des propriétés de classe lors de l'héritage ?
Si une sous-classe déclare une propriété avec le même nom que celle du parent, un shadowing se produit. Cependant, en accédant via super ou self, la propriété correspondante sera choisie. Il est préférable de ne pas utiliser les mêmes noms sans nécessité.
Dans la classe Account, l'un des développeurs a accidentellement utilisé la variable balance comme nom de paramètre de fonction et a à nouveau utilisé let balance = ... à l'intérieur de la fonction. En raison du shadowing, le calcul a été effectué avec une valeur incorrecte et la fonction retournait un résultat faux, ce qui n'a été découvert qu'à un stade avancé des tests.
Avantages :
Inconvénients :
Toute l'équipe s'est mise d'accord pour utiliser des préfixes (par exemple, inputBalance) ou d'appliquer toujours self pour les références aux propriétés. En conséquence, les erreurs liées au shadowing ont pratiquement disparu, et la maintenance du code a été simplifiée.
Avantages :
Inconvénients :