Ответ
Чтобы класс можно было использовать как ключ в Dictionary, он должен соответствовать протоколу Hashable (который, в свою очередь, наследует протокол Equatable).
Требования:
- Реализовать
Equatable: Определить оператор==для сравнения двух экземпляров на равенство. - Реализовать
Hashable: Реализовать методhash(into:), который передаёт все значимые для равенства свойства в предоставленныйHasher.
Ключевое правило: Если два экземпляра равны согласно ==, то их хеш-значения, сгенерированные hash(into:), должны быть одинаковыми. Обратное не обязательно — разные объекты могут иметь одинаковый хеш (коллизия), но это снижает производительность словаря.
class User: Hashable {
let id: UUID
let username: String
init(id: UUID, username: String) {
self.id = id
self.username = username
}
// 1. Реализация Equatable
static func == (lhs: User, rhs: User) -> Bool {
// Для равенства пользователей достаточно сравнить их уникальный id
return lhs.id == rhs.id
}
// 2. Реализация Hashable
func hash(into hasher: inout Hasher) {
// В хеширование включаем только свойства, используемые в `==`
hasher.combine(id)
}
}
// Теперь класс User можно использовать как ключ
var scores: [User: Int] = [:
let user = User(id: UUID(), username: "Alice")
scores[user] = 100