Set's contains method returns different value at different time

房东的猫 提交于 2019-12-02 04:33:36

The synthesized implementation of the Hashable requirement uses all stored properties of a struct, in your case string and number. Your implementation of == is only based on the string:

let first = SimpleStruct(string: "a", number: 2)
let second = SimpleStruct(string: "a", number: 3)

print(first == second) // true
print(first.hashValue == second.hashValue) // false

This is a violation of a requirement of the Hashable protocol:

Two instances that are equal must feed the same values to Hasher in hash(into:), in the same order.

and causes the undefined behavior. (And since hash values are randomized since Swift 4.2, the behavior can be different in each program run.)

What probably happens in your test is that the hash value of second is used to determine the “bucket” of the set in which the value would be stored. That may or may not be the same bucket in which first is stored. – But that is an implementation detail: Undefined behavior is undefined behavior, it can cause unexpected results or even runtime errors.

Implementing

var hashValue: Int {
    return string.hashValue
}

or alternatively (starting with Swift 4.2)

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

fixes the rule violation, and therefore makes your code behave as expected.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!