== et === en Swift : quelle est la différence et ce qui se cache sous le capot

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

Pourquoi deux signes égal en Swift et que cachent-ils ?

\n\n

Avez-vous déjà écrit en Swift et soudainement rencontré l'opérateur étrange === ? La première pensée : "Une faute de frappe ? Ou est-ce une sorte de super-égal ?" En réalité, ce n'est pas une faute de frappe, mais un mécanisme puissant qui change fondamentalement la logique de comparaison. Si vous travaillez avec des classes, des structures ou des closures, comprendre la différence entre == et === n'est pas de la théorie, mais une nécessité. Sans cela, vous risquez d'obtenir des bogues difficiles à détecter.

\n\n

Dans cet article, nous allons regarder "sous le capot" de Swift, analyser comment fonctionnent les deux opérateurs, et apprendre à choisir le bon outil pour chaque tâche. Prêts ? C'est parti.

\n\n

Qu'est-ce que l'opérateur d'égalité == ?

\n\n

L'opérateur == est votre "ami" standard pour comparer des valeurs. Il vérifie si deux objets sont égaux par leur contenu. Mais il y a un détail : Swift ne sait pas ce que signifie "égaux" pour votre propre type de données. Par conséquent, pour utiliser ==, votre type doit être conforme au protocole Equatable.

\n\n

Voici à quoi cela ressemble pour les types intégrés :

\n\n
let a = 5\nlet b = 5\nprint(a == b) // true, car les valeurs sont identiques\n\nlet name1 = "Alice"\nlet name2 = "Alice"\nprint(name1 == name2) // true, les chaînes sont identiques
\n\n

Pour les classes et les structures, vous devez implémenter vous-même Equatable. Par exemple :

\n\n
struct User {\n    let id: Int\n    let name: String\n}\n\nextension User: Equatable {\n    static func == (lhs: User, rhs: User) -> Bool {\n        return lhs.id == rhs.id && lhs.name == rhs.name\n    }\n}\n\nlet user1 = User(id: 1, name: "John")\nlet user2 = User(id: 1, name: "John")\nprint(user1 == user2) // true, le contenu correspond
\n\n

Notez bien : == compare les valeurs, et non les références. Pour les structures, c'est évident, mais avec les classes, les choses deviennent intéressantes.

\n\n

L'opérateur d'identité === : quand deux objets sont une seule et même chose

\n\n

L'opérateur === (triple égal) ne compare pas le contenu, mais l'identité des références. Il répond à la question : "Les deux variables pointent-elles vers le même objet en mémoire ?"

\n\n

Cet opérateur fonctionne uniquement avec les types par référence : les classes et les closures (les closures sont aussi des types par référence). Pour les structures et les énumérations, il n'existe tout simplement pas — le compilateur générera une erreur.

\n\n

Regardez l'exemple :

\n\n
class Car {\n    var model: String\n    init(model: String) {\n        self.model = model\n    }\n}\n\nlet car1 = Car(model: "Tesla")\nlet car2 = Car(model: "Tesla")\nlet car3 = car1\n\nprint(car1 == car2) // false, si Equatable n'est pas implémenté\nprint(car1 === car2) // false, objets différents\nprint(car1 === car3) // true, même référence
\n\n

Ici, car1 et car2 sont deux objets différents avec le même contenu. Alors que car3 est simplement un autre nom pour le même objet que car1. === le montre clairement.

\n\n

Comment cela fonctionne sous le capot : mémoire et pointeurs

\n\n

Pour comprendre la différence, il faut regarder dans la mémoire. Lorsque vous créez une instance d'une classe, Swift lui alloue une zone dans le tas (heap) et retourne un pointeur vers cette zone. La variable stocke précisément le pointeur, et non l'objet lui-même.

\n\n
    \n
  • == compare le contenu via le pointeur : il appelle votre implémentation de Equatable, qui peut examiner les champs de l'objet.
  • \n
  • === compare les pointeurs eux-mêmes : si deux pointeurs mènent à la même adresse mémoire, le résultat est true.
  • \n
\n\n

Pour les structures, c'est plus simple : elles sont stockées dans la pile (stack) et sont copiées lors de l'affectation. Par conséquent, === n'a pas de sens pour elles — deux structures différentes seront toujours des objets différents en mémoire, même si leur contenu est

Blogs

Book Recommendations