提问人:Kendall Helmstetter Gelner 提问时间:7/9/2019 更新时间:7/9/2019 访问量:1092
Swift 5.0 “设置”允许重复值
Swift 5.0 "Set" allowing duplicate values
问:
在 Swift 5.0 Playground 中,我正在尝试扩展,以便它将点视为哈希和相等的整数值。CGPoint
令我惊讶的是,即使在覆盖和开启之后,一组 CGPoints 仍然具有相似的值作为独立点,即使两个元素应该碰撞并且只保留一个。您是否需要重写其他方法才能按预期完成此工作?hash()
==
CGPoint
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
答:
3赞
rob mayoff
7/9/2019
#1
rmaddy 和 Martin R 发现了问题,但这里是一个答案:不使用您的函数。它使用标准库中定义的函数,因为在标准库中定义。你可以通过调用 is your function 来证明这一点。当您在 中插入一个点时,您会看到您的点没有运行。Set
==
==
Set
print
==
Set
print
评论
1赞
Kendall Helmstetter Gelner
7/9/2019
谢谢,我被我比较 p2 == p3 的行误导了,这产生了对该方法的一些调用,使我认为集合正在使用它。
评论
hash(into:)
CGPoint
Equatable
==
In some cases, oldMember may be distinguishable from newMember by identity comparison or some other means."
==