Enum как ключ для словаря - PullRequest
0 голосов
/ 14 июня 2019

У меня есть словарь

var observers: [ObservingType: [MessageObserverManager?]] = .init()

в качестве ключа, который я использую здесь enum, но по некоторым причинам он не работает, словарь не создает никаких объектов с этими ключами.

enum ObservingType: Hashable {
case messages(codeId: Int, codeTwoId: Int)
case allMessages
case threadMessages(otherId: Int)

static func == (lhs: ObservingType, rhs: ObservingType) -> Bool {
    return lhs.hashValue == rhs.hashValue
}

func hash(into hasher: inout Hasher) {
    switch self {
    case .messages(let codeId, let codeTwoId):
        hasher.combine(codeId)
        hasher.combine(codeTwoId)
        hasher.combine(1000 / Int.random(in: 1...25))

    case .allMessages:
        hasher.combine(100000 / Int.random(in: 1...25))

    case .threadMessages(let otherId):
        hasher.combine(otherId)
        hasher.combine(100000000 / Int.random(in: 1...25))
    }
}

Неужели вы советуете, что не так с enum?

Наблюдатели [.allMessages] ?. isEmpty ??ложь else {наблюдатели [.allMessages] ?.enum, извините и спасибо за помощь!

1 Ответ

2 голосов
/ 14 июня 2019

Ваша реализация == неверна.Не сравнивайте значения хешей.Сравните фактические значения.Помните, что два неравных значения могут иметь одно и то же значение хеш-функции.

Ваша реализация hash не должна использовать случайные числа.Удалить эти строки.Значение хеш-функции для данного значения должно быть устойчивым (по крайней мере, во время одного выполнения приложения).Вы не можете искать значения в словаре хэша ключей, которые постоянно меняются.

Самое простое решение, в этом случае, это позволить компилятору генерировать и ==, и hash(into:).Тогда ваш код становится:

enum ObservingType: Hashable {
    case messages(codeId: Int, codeTwoId: Int)
    case allMessages
    case threadMessages(otherId: Int)
}

Это намного проще, и теперь вы можете использовать enum в качестве ключей для словаря.

...