我在考虑 Swift 如何确保 Set 的唯一性,因为我已经免费将我的一个 obj 从Equatable
变成Hashable
了,所以我想出了这个简单的 Playground
struct SimpleStruct: Hashable {
let string: String
let number: Int
static func == (lhs: SimpleStruct, rhs: SimpleStruct) -> Bool {
let areEqual = lhs.string == rhs.string
print(lhs, rhs, areEqual)
return areEqual
}
}
var set = Set<SimpleStruct>()
let first = SimpleStruct(string: "a", number: 2)
set.insert(first)
所以我的第一个问题是:
static func ==
每当我在集合中插入新的 obj 时,都会调用该方法吗?
我的问题来自这个想法:
对于Equatable
obj,为了做出这个决定,唯一能保证两个 obj 相同的方法就是询问 的结果static func ==
。
对于Hashable
obj,一种更快的方法是比较hashValue
s... 但是,就像我的情况一样,默认实现将同时使用string
and number
,与==
逻辑相反。
因此,为了测试Set
行为方式,我刚刚添加了一条打印语句。
我发现有时我得到了打印声明,有时没有。就像有时hashValue
不足以做出这个决定......所以该方法并不是每次都被调用。奇怪的...
所以我尝试添加两个相等的对象,想知道结果会是什么set.contains
let second = SimpleStruct(string: "a", number: 3)
print(first == second) // returns true
set.contains(second)
奇迹般的奇迹,在操场上启动了几次,我得到了不同的结果,这可能会导致不可预知的结果......添加
var hashValue: Int {
return string.hashValue
}
它消除了任何意想不到的结果,但我的疑问是:
为什么在没有自定义hashValue
实现的情况下,==
有时会被调用,有时却不会?苹果应该避免这种意想不到的行为吗?