ПрограммированиеiOS разработчик

Объясните разницу между оператором == и методом Equatable в Swift. Как корректно реализовать сравнение экземпляров собственных типов?

Проходите собеседования с ИИ помощником Hintsage

Ответ

В Swift оператор == используется для проверки равенства двух значений. Для того чтобы этот оператор можно было использовать с пользовательскими типами, тип должен соответствовать протоколу Equatable и реализовывать статическую функцию ==.

Реализация должна быть симметричной и транзитивной. Пример:

struct Person: Equatable { let name: String let age: Int static func ==(lhs: Person, rhs: Person) -> Bool { return lhs.name == rhs.name && lhs.age == rhs.age } }

Стоит помнить, что если ваш тип не реализует ==, то попытка сравнения двумя такими экземплярами приведет к ошибке компиляции.

Вопрос с подвохом

Вопрос: Если структура или класс наследует протокол Equatable, почему иногда оператор == можно не реализовывать явно?

Ответ: Для структур, все свойства которых также соответствуют Equatable, Swift автоматически синтезирует реализацию оператора ==. Но если в типе есть свойства, не являющиеся Equatable, или тип — класс с кастомным наследованием, синтез не произойдет, и потребуется реализовать оператор вручную.

struct Point: Equatable { var x: Int var y: Int // Реализация == не нужна, он синтезируется автоматически }

Примеры реальных ошибок из-за незнания тонкостей темы.


История

В одном проекте разработчик добавил свойство типа UIImage в структуру, уже соответствующую Equatable. Ошибка компиляции возникла, потому что UIImage не реализует Equatable, а значит, для структуры нельзя было автоматически синтезировать ==. Решение — реализовать оператор == вручную, сравнивая только существенные для логики свойства.


История

Ошибка возникла после внесения нового свойства в структуру, но забыв добавить его сравнение в пользовательский оператор ==. Это привело к некорректной логике при работе с коллекциями и багам в пользовательском фильтре.


История

В проекте был написан custom-класс без реализации Equatable, но его попытались использовать в Set. Это привело к runtime-ошибке, так как Set требует, чтобы элементы были уникальны (и, следовательно, Equatable).