Swift 5.0 "Set" 允许重复值
Swift 5.0 "Set" allowing duplicate values
在 Swift 5.0 Playground 中,我在 CGPoint
上进行扩展试验,这样它就散列和相等性而言将点视为整数值。
令我惊讶的是,即使在 CGPoint
上覆盖 hash()
和 ==
之后,一组 CGPoints 仍然保持与独立点相似的值,即使两个元素应该发生碰撞并保持只有一个。您是否需要在 CGPoint
上覆盖其他一些方法才能按预期进行此工作?
P.S。在实践中最好不要这样做,因为它可能会影响系统,最好提供某种包装器来管理平等。但是我想知道为什么这不起作用。
Playground 内容以及执行后给出的结果:
// Extension to treat points as integer values (not reccomended approach)
extension CGPoint : Hashable {
public func hash(into hasher: inout Hasher) {
hasher.combine(Int(x))
hasher.combine(Int(y))
}
static public func == (lhs: CGPoint, rhs: CGPoint) -> Bool {
return Int(lhs.x) == Int(rhs.x) && Int(lhs.y) == Int(rhs.y)
}
}
var pSet : Set<CGPoint> = []
let p1 = CGPoint.zero
let p2 = CGPoint(x: 20.1, y: 30)
let p3 = CGPoint(x:20, y: 30)
pSet.insert(p1) // inserted true
pSet.insert(p2) // inserted true
pSet.insert(p3) // inserted true(!), should be false
p2 == p3 // true
pSet.count // 3(!), should be two
p2.hashValue // Same as p3
p3.hashValue // Same as p2
pSet // shows all three values, all points defined, should be two values only
rmaddy 和 Martin R 确定了问题所在,但这里作为答案:Set
没有使用您的 ==
函数。它使用标准库中定义的==
函数,因为Set
是在标准库中定义的。您可以通过调用 print
是您的 ==
函数来证明这一点。当您在 Set
中插入一个点时,您会看到您的 print
没有 运行。
在 Swift 5.0 Playground 中,我在 CGPoint
上进行扩展试验,这样它就散列和相等性而言将点视为整数值。
令我惊讶的是,即使在 CGPoint
上覆盖 hash()
和 ==
之后,一组 CGPoints 仍然保持与独立点相似的值,即使两个元素应该发生碰撞并保持只有一个。您是否需要在 CGPoint
上覆盖其他一些方法才能按预期进行此工作?
P.S。在实践中最好不要这样做,因为它可能会影响系统,最好提供某种包装器来管理平等。但是我想知道为什么这不起作用。
Playground 内容以及执行后给出的结果:
// Extension to treat points as integer values (not reccomended approach)
extension CGPoint : Hashable {
public func hash(into hasher: inout Hasher) {
hasher.combine(Int(x))
hasher.combine(Int(y))
}
static public func == (lhs: CGPoint, rhs: CGPoint) -> Bool {
return Int(lhs.x) == Int(rhs.x) && Int(lhs.y) == Int(rhs.y)
}
}
var pSet : Set<CGPoint> = []
let p1 = CGPoint.zero
let p2 = CGPoint(x: 20.1, y: 30)
let p3 = CGPoint(x:20, y: 30)
pSet.insert(p1) // inserted true
pSet.insert(p2) // inserted true
pSet.insert(p3) // inserted true(!), should be false
p2 == p3 // true
pSet.count // 3(!), should be two
p2.hashValue // Same as p3
p3.hashValue // Same as p2
pSet // shows all three values, all points defined, should be two values only
rmaddy 和 Martin R 确定了问题所在,但这里作为答案:Set
没有使用您的 ==
函数。它使用标准库中定义的==
函数,因为Set
是在标准库中定义的。您可以通过调用 print
是您的 ==
函数来证明这一点。当您在 Set
中插入一个点时,您会看到您的 print
没有 运行。