Swift set equatable 有时为真有时为假

Swift set equatable sometimes true sometimes false

我有一个符合 Hashable 的结构。这个模型放在Set。当我检查集合是否包含模型时随机 returns true/false。这是为什么?

enum Feature: String {
    case a
    case b
}

struct FeatureState: Hashable {
    let feature: Feature
    let isEnabled: Bool
}

extension FeatureState: Equatable {

    static func == (lhs: FeatureState, rhs: FeatureState) -> Bool {
        lhs.feature == rhs.feature
    }
}

let fs1 = FeatureState(feature: .a, isEnabled: false)
let fs2 = FeatureState(feature: .a, isEnabled: true)

featureStates.insert(fs1)
print(featureStates.contains(fs2)) // sometimes true, sometimes false

Set.contains 使用散列来检查元素是否已经是 Set 的一部分,并且仅当两个元素的散列值相同时才使用 == 运算符。因此,您需要提供自己的 hash(into:) 实现,使哈希值仅依赖于 feature,而不是 isEnabled.

struct FeatureState {
    let feature: Feature
    let isEnabled: Bool
}

extension FeatureState: Hashable {
    static func == (lhs: FeatureState, rhs: FeatureState) -> Bool {
        lhs.feature == rhs.feature
    }

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