DevPrep

Все темы › Язык Swift

Equatable и Hashable — зачем? Почему ключ Dictionary должен быть Hashable?

Junior PRO

Суть

Equatable даёт оператор == — «эти два значения одинаковы». Hashable расширяет Equatable и добавляет hash(into:) — сворачивание значения в число через Hasher. Dictionary и Set требуют Hashable от ключа/элемента, потому что ищут не перебором, а по хешу: хеш → индекс бакета, затем == для разрешения коллизий. Это даёт O(1) в среднем (в худшем случае, при массовых коллизиях, — O(n)).

struct User: Hashable {          // == и hash(into:) синтезируются по всем полям
    let id: Int
    let name: String
}

struct Tag: Hashable {           // своя семантика: регистр не важен
    let value: String
    static func == (l: Tag, r: Tag) -> Bool {
        l.value.lowercased() == r.value.lowercased()
    }
    func hash(into hasher: inout Hasher) {
        hasher.combine(value.lowercased())   // равные → равный хеш
    }
}

let tags: Set<Tag> = [Tag(value: "Swift"), Tag(value: "swift")]
print(tags.count)                 // 1
var ages: [User: Int] = [:]
ages[User(id: 1, name: "Ann")] = 30

Продолжение ответа с кодом и уточняющими вопросами интервьюера — в приложении DevPrep.

Полный ответ — в DevPrep

Потренируйтесь перед собеседованием

В DevPrep эти ответы превращаются в задачи на минуту: что напечатает код, найди баг, пробное собеседование. По задаче в день.

Скачать DevPrep в App Store