Ответ
Операторы решают разные задачи сравнения:
-
==(Оператор равенства)- Сравнивает значения на эквивалентность.
- Требует соответствия типов сравниваемых операндов протоколу
Equatable. - Реализуется разработчиком для пользовательских типов.
-
===(Оператор идентичности)- Сравнивает ссылки на экземпляры классов.
- Проверяет, указывают ли две переменные/константы на один и тот же объект в памяти.
- Применим только к экземплярам классов (ссылочным типам).
Практический пример:
class Person: Equatable {
let id: Int
init(id: Int) { self.id = id }
static func == (lhs: Person, rhs: Person) -> Bool {
return lhs.id == rhs.id // Сравниваем значения ID
}
}
let person1 = Person(id: 1)
let person2 = Person(id: 1)
let person3 = person1
print(person1 == person2) // true — значения ID равны (1 == 1)
print(person1 === person2) // false — это разные объекты в памяти
print(person1 === person3) // true — обе ссылки указывают на один объект
Итог: Используйте == для сравнения по значению, === — чтобы проверить, являются ли две переменные ссылками на один экземпляр класса.
Ответ 18+ 🔞
А, слушай, вот эта тема про == и === — это классика, на которой народ постоянно ебётся, как слепой кот в мясном отделе. Сейчас разложу по полочкам, чтобы ты не был как тот Герасим, который только «Му-му» может мычать.
Вот смотри, в чём тут вся соль, блядь.
Есть у нас два оператора, которые выглядят почти одинаково, но делают хуйню совершенно разную. Как близнецы, где один — гениальный хирург, а второй — пиздопроебибна, которая вчера у соседа газон скосила и продала.
== (Оператор равенства, он же «похожи ли они по смыслу?»)
Этот парень — интеллигент. Он не лезет в память, не проверяет, один ли это физический объект. Его задача проще: понять, равны ли значения. Как будто сравниваешь две бутылки воды из разных магазинов. Вода одинаковая? Вода. Значит, по значению — равны. Но бутылки-то — разные, ёпта!
Чтобы этот оператор работал с твоими кастомными типами (структурами, классами), ты должен научить их этому протоколу Equatable. Без этого Swift просто разведёт руками и скажет: «Чувак, я нихуя не понимаю, как сравнивать твои Person или Car. Научи меня».
=== (Оператор идентичности, он же «а это один и тот же кусок памяти, сука?»)
А вот это уже бандит с большой дороги. Его не интересует «значение». Его интересует только один вопрос: указывают ли эти две переменные на один и тот же, блядь, объект в оперативке? Применим он ТОЛЬКО к классам, потому что только они — ссылочные типы и живут там, в этой куче.
Представь, что у тебя есть один бумажник. Ты можешь назвать его мойКошелёк, а твой друг может назвать его заначкаНаПиво. Это две разные ссылки (мойКошелёк и заначкаНаПиво), но указывают они на один и тот же, ёбта, бумажник. Вот === это и проверяет.
А теперь практика, чтобы мозг не взорвался:
class Person: Equatable {
let id: Int
init(id: Int) { self.id = id }
// Вот тут мы учим Swift сравнивать наших Person по ЗНАЧЕНИЮ (по id)
static func == (lhs: Person, rhs: Person) -> Bool {
return lhs.id == rhs.id // Сравниваем значения ID, а не сами объекты!
}
}
// Создаём два ОТДЕЛЬНЫХ объекта. Два разных чувака в памяти.
let person1 = Person(id: 1)
let person2 = Person(id: 1)
// А это просто вторая этикетка на ПЕРВЫЙ объект.
let person3 = person1
print(person1 == person2) // true — потому что id у обоих = 1. По ЗНАЧЕНИЮ они одинаковые.
print(person1 === person2) // false — это, блядь, РАЗНЫЕ объекты в памяти! Две разные квартиры с одинаковой мебелью.
print(person1 === person3) // true — УРА! Обе переменные смотрят на один и тот же объект. person3 — это просто псевдоним для person1.
Итог, чтобы запомнить навсегда:
==— «Вы одинаковые по содержанию?» (Работает и со структурами, и с классами, если ониEquatable).===— «Вы, сука, одна и та же штука в памяти?» (Работает ТОЛЬКО с классами).
Используешь ==, когда тебе важно, что внутри (например, сравнить два контакта по номеру телефона). Хватаешься за ===, когда нужно быть на 100% уверенным, что ты работаешь с тем самым, конкретным экземпляром, а не с его клоном. Всё, вопрос закрыт, можно идти пить чай.