遵循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
相关产品推荐
相关产品推荐

