swift - 枚举作为字典的键

标签 swift dictionary hash enums

我有一本字典

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

我在这里使用枚举作为键,但由于某些原因它不起作用,字典不会使用这些键创建任何对象。

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))
    }
}

冷你建议枚举有什么问题?

守卫观察员[.allMessages]?.isEmpty ??假的其他{ 观察者[.allMessages]?.append(观察者)

    return
}

observers[.allMessages] = [observer]

这是我用来添加值的代码,问题是我没有创建那些数组,所以原因不在枚举中,抱歉,感谢您的帮助!

最佳答案

您对 == 的实现不正确。不要比较哈希值。比较实际值。请记住,允许两个不相等的值具有相同的哈希值。

hash 的实现不应该使用随机数。删除那些行。给定值的哈希值需要稳定(至少在应用程序的单次执行期间)。您无法在不断变化的键散列字典中查找值。

在这种情况下,最简单的解决方案是让编译器同时生成==hash(into:)。然后你的代码变成:

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

它更简单,您现在可以使用 enum 作为字典的键。

关于swift - 枚举作为字典的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56602812/

相关文章:

json - 在 SWIFT 4 中解析嵌套的 JSON

swift - 在应用程序中显示一次 UIAlert

python - 如何在 Django 模板中迭代字典的列表值

java - 计算 NS2 中 UDP 数据包的哈希值

php - 与盐渍 SHA512 相比,盐渍 SHA1 有多不安全

ios - 如何在用户点击 Ui 按钮时将相关数据加载到表中?

ios - 使用结构体时不断收到 "Cannot assign to value: 'calculateBMI' is a method"

c++ - 海湾合作委员会 4.1.2 : error: integer constant is too large for ‘long’ type

c# - 如何从字典中为某些键选择所有键值对

Python dict 如何在一行中创建 key 或更新 key ?