MiddleКодЧастоЕщё не отвечали
Когда Swift синтезирует Equatable/Hashable и когда ==/hash(into:) надо писать вручную?
У вас есть модель User с полями id, name и датой lastSeen. Два пользователя одинаковы, когда совпадает их id, независимо от остальных полей.
Требования:
- Сделайте
UserконформнымEquatableиHashable. - Основывайте и равенство, и хеширование только на
id. - Не полагайтесь на синтез компилятора, который сравнил бы каждое хранимое свойство.
struct User {
let id: UUID
var name: String
var lastSeen: Date
// добавьте конформность здесь
}
Напишите реализации == и hash(into:).
Swift синтезирует Equatable/Hashable, когда каждое хранимое свойство конформно и вы объявляете конформность в файле типа. Пишите их вручную, когда равенство должно игнорировать поля — сравнивайте только id в == и подавайте лишь id в hash(into:).
- ✗Думают, что синтез работает, даже когда хранимое свойство не конформно
- ✗Подают в
==иhash(into:)разные поля, нарушая контракт хеша - ✗Считают, что оба метода всегда надо писать вручную
- →Почему равные значения обязаны давать равные хеши?
- →Где надо объявить конформность, чтобы синтез сработал?
Равенство и хеширование опираются только на id:
extension User: Equatable, Hashable {
static func == (lhs: User, rhs: User) -> Bool {
lhs.id == rhs.id
}
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
Синтез компилятора сравнивал и хешировал бы также name и lastSeen, поэтому тот же пользователь с более новым lastSeen считался бы другим. Подача только id в оба метода хранит контракт: равные значения обязаны давать равные хеши, а здесь оба берутся лишь из id.