Ответ
Протокол Hashable наследует протокол Equatable. Поэтому реализация == является обязательным требованием.
Логическая причина: Для корректной работы хеш-таблиц (как в Set или Dictionary) должно выполняться ключевое правило:
Если два объекта равны (
a == bвозвращаетtrue), то их хеш-значения должны быть одинаковыми (a.hashValue == b.hashValue).
Обратное утверждение не требуется — разные объекты могут иметь одинаковый хеш (коллизия), и структура данных корректно это обработает.
Пример реализации:
struct User: Hashable {
let id: UUID
let username: String
// 1. Определяем равенство по уникальному id
static func == (lhs: User, rhs: User) -> Bool {
return lhs.id == rhs.id
}
// 2. В хеш включаем только id, соблюдая правило
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
// Использование в Set
let user1 = User(id: uuid1, username: "Alice")
let user2 = User(id: uuid1, username: "Alice_Changed") // Тот же id!
print(user1 == user2) // true, т.к. id совпадают
print(Set([user1, user2]).count) // 1. В Set попал только один объект
Последствия нарушения правила: Если равные объекты дают разный хеш, они могут быть неправильно размещены в Set или Dictionary, что приведет к логическим ошибкам (дубликатам или потере данных).