В чем разница между операторами == и === в Swift?

Ответ

Операторы решают разные задачи сравнения:

  • == (Оператор равенства)

    • Сравнивает значения на эквивалентность.
    • Требует соответствия типов сравниваемых операндов протоколу 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% уверенным, что ты работаешь с тем самым, конкретным экземпляром, а не с его клоном. Всё, вопрос закрыт, можно идти пить чай.