Swift 5.0 "Set", позволяющий дублировать значения - PullRequest
3 голосов
/ 09 июля 2019

На игровой площадке Swift 5.0 я экспериментировал с расширениями на CGPoint, чтобы точки обрабатывались как целочисленные значения с точки зрения хеширования и равенства.

К моему удивлению, даже после переопределения hash() и == на CGPoint набор CGPoints все еще содержал аналогичные значения в качестве независимых точек, даже если два элемента должны были сталкиваться и сохранять только один. Есть ли какой-то другой метод, который вам нужно переопределить на CGPoint, чтобы эта работа работала как положено?

P.S. Вероятно, лучше не делать этого на практике, так как это может повлиять на систему, лучше предоставить какую-то оболочку для управления равенством. Но я хотел бы знать, почему это не работает.

Содержимое игровой площадки вместе с результатами, полученными после выполнения:

// 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

1 Ответ

2 голосов
/ 09 июля 2019

rmaddy и Martin R определили проблему, но вот как ответ: Set не использует вашу функцию ==. Он использует функцию ==, определенную в стандартной библиотеке, поскольку Set определена в стандартной библиотеке. Вы можете доказать это, вызвав print - это ваша == функция. Когда вы вставите точку в Set, вы увидите, что ваш print не работает.

...