In a Swift 5.0 Playground, I was experimenting with extensions on CGPoint
such that it treated points as integer values in terms of hashing and equality.
To my surprise, even after overriding hash()
and ==
on CGPoint
, a Set of CGPoints still held similar values as independent points even though two elements should have collided and kept only one. Is there some other method you would need to override on CGPoint
to have this work as expected?
P.S. Probably best not to do this in practice as it might affect the system, better to provide some kind of wrapper to manage equality. But I would like to know why this does not work.
The Playground contents along with results given after execution:
// 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