我一生都相信,
Set
会在插入新值时替换现有值以保持其独特的属性。但今天我很惊讶,事实并非如此,
代码:
enum Action {
case edit
case delete
case update
}
struct Object: Equatable, Hashable {
let id: String
let action: Action
let code: UInt8
var description: String {
return "`\(self.action)` on `\(self.id)` with #\(self.code)"
}
init(id: String, action: Action, code: UInt8) {
self.id = id
self.action = action
self.code = code
}
func hash(into hasher: inout Hasher) {
hasher.combine(self.id)
}
static func == (lhs: Object, rhs: Object) -> Bool {
return lhs.id == rhs.id
}
}
所以我使用属性
id
来保持唯一性。当我插入具有相同 id
和不同其他值的新对象时,Set
将保留旧对象而不是新插入。
var collection = Set<Object>()
let obj1 = Object(id: "1", action: .delete, code: 1) // `delete` on `1` with #1
collection.insert(obj1)
let obj2 = Object(id: "1", action: .update, code: 4) // `update` on `1` with #4
collection.insert(obj2)
print(collection.first!.description) // `delete` on `1` with #1
正如我所想,印刷品应该是
code: 4
,但它是code: 1
。实际上我确实在一个search-hungry
项目和很多地方使用了该技术,但今天它并没有达到预期的效果,经过长时间的调试我确实发现了这一点。
这是
Set
在 Swift 中工作的方式还是我做错了什么?
问题在于您忽略了插入方法的结果。您应该尝试插入,如果没有插入,您可以更新该集。比如:
if !collection.insert(obj2).inserted {
collection.update(with: obj2)
}