Какие типы данных могут быть ключами в словаре (Dictionary) в Swift?

«Какие типы данных могут быть ключами в словаре (Dictionary) в Swift?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Ключом в словаре Dictionary<Key, Value> в Swift может быть любой тип, соответствующий протоколу Hashable. Этот протокол требует реализации метода hash(into:) и наследует от Equatable.

Типы, которые уже соответствуют Hashable по умолчанию:

  • Все базовые типы: Int, String, Bool, Double, Float и т.д.
  • Optional (Wrapped?), если WrappedHashable.
  • Array, Set, Dictionary, Range, если их элементы — Hashable.
  • Перечисления (enum) без ассоциированных значений или с Hashable ассоциированными значениями.

Пользовательские типы: Структуры (struct) и перечисления (enum) автоматически получают синтезированную реализацию Hashable, если все их хранимые свойства также Hashable. Для классов (class) реализацию необходимо прописать вручную.

Почему Hashable? Словари используют хеш-таблицы для быстрого доступа (O(1) в среднем). Ключ должен быть однозначно идентифицируем (Equatable) и иметь стабильный хеш-код (Hashable).

Пример с пользовательской структурой:

// Автоматическое соответствие Hashable, так как все свойства (UUID, String) Hashable.
struct User: Hashable {
    let id: UUID
    let username: String
}

// Использование User как ключа в словаре
var userRoles: [User: String] = [
    User(id: UUID(), username: "alice"): "admin",
    User(id: UUID(), username: "bob"): "editor"
]

// Доступ по ключу
if let role = userRoles[User(id: someUUID, username: "alice")] {
    print(role) // Напечатает "admin", если UUID совпадает
}

Что не может быть ключом: Типы, не соответствующие Hashable (например, пользовательский класс без явной реализации) или содержащие не-Hashable свойства.