You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

遵循Hashable协议的字典键更新值时是否会替换为新的引用对象

问题解答

答案是不会,字典的键不会被更新为exam2的引用,dict.keys中存储的仍然是最初的exam1引用。

原理说明

Swift 字典对键的匹配逻辑是先校验哈希值是否相等,再通过==运算符判断是否为等效键。当你使用exam2执行赋值操作时,因为exam1和exam2的ID属性一致,哈希值相等且==返回true,字典会判定两者为同一个键,此时只会更新该键对应的存储值,不会替换已经保存在字典中的键实例。

你可以通过以下代码验证这个行为:

class Example: Hashable {
    let ID: Int
    let name: String

    init(ID: Int, name: String) {
        self.ID = ID
        self.name = name
    }

    static func == (lhs: Example, rhs: Example) -> Bool {
        lhs.ID == rhs.ID
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(ID)
    }
}

// 测试逻辑
var dict: [Example: Int] = [:]
let exam1 = Example(ID: 6, name: "goon")
dict[exam1] = 7
print(dict.keys.first?.name as Any) // 输出:Optional("goon")

let exam2 = Example(ID: 6, name: "pie")
dict[exam2] = 8
print(dict.keys.first?.name as Any) // 仍然输出:Optional("goon")

注意事项

你遇到的反直觉场景本质是Hashable协议实现不符合规范导致的:Swift 要求所有通过==判断为相等的实例,其所有影响相等性的属性都应该完全一致,如果你仅用ID判断相等,就会出现两个实例属性不同但被判定为相等的异常情况,实际开发中要避免这类实现。

内容的提问来源于stack exchange,提问作者anon12345

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 18:36:05