Swift - не может получить значение словарного класса, расширяемого из класса - PullRequest
0 голосов
/ 13 октября 2018

Простая проблема, но я не знаю почему !!

  • Создайте класс - A, а класс B расширяется от B.
  • Создайте коллекцию

    общедоступная переменная hm: [B: Int] = [:]

Класс A - определено:

class A : Hashable {
    var x : Double = 0
    var y : Double = 0
    init(x : Double, y : Double) {
        self.x = x
        self.y = y
    }
    var hashValue : Int {
        get {
            // IMPORTANT!!! Do some operations to generate a unique hash.
            return ObjectIdentifier(self).hashValue
        }
    }
    static func == (lhs: A, rhs: A) -> Bool {
        //return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
        return (lhs.x == rhs.x && lhs.y == rhs.y)
    }
}

class B : A {

}

Проверка функции для получения значения коллекции - хм.

     func check(a1 : B, a2 : B){
        print("\na1: \(a1.x)  \(a1.y)")
        if let y1 = hm[a1] {
            print(y1)
        }else{
            print("false a1")
        }

        print("\na2: \(a2.x)  \(a2.y)")
        if let y2 = hm[a2] {
            print(y2)
        }else{
            print("false a2")
        }
    }

и, наконец, создание функции test () является главной для тестирования.

func test() -> Void {
        let a1 : B = B(x: 9.0, y: 12.0)
        let a2 : B = B(x: 19.0, y: 42.0)


        hm[a1] = 99
        hm[a2] = 20

        let a3 : B = B(x: 9.0, y: 12.0)
        let a4 : B = B(x: 19.0, y: 42.0)

        print("----Content of hm-----")
        for (key, val) in hm {
            print("x: \(key.x)  | y: \(key.y)  | val: = \(val)")
        }

        check(a1: a3, a2: a4)
    }

В вызове основного потока test (),Вывод:

----Content of hm-----
x: 19.0  | y: 42.0  | val: = 20
x: 9.0  | y: 12.0  | val: = 99

a1: 9.0  12.0
99

a2: 19.0  42.0
false a2

Почему, выведите «false a2» -> not found a2 внутри коллекции hm?

Для сравнения 2 объекта, которые я использую: (lhs.x == rhs.x && lhs.y == rhs.y).(если использовать ObjectIdentifier, тогда результат всегда будет ложным для сравнения)

Спасибо за объяснение.

enter image description here

Ответы [ 2 ]

0 голосов
/ 14 октября 2018

Удалите вашу реализацию hashValue и замените вставьте это вместо:

func hash(into hasher: inout Hasher) {
    x.hash(into:&hasher)
    y.hash(into:&hasher)
}
0 голосов
/ 14 октября 2018

Я не знаю, почему он так себя ведет, но я могу сказать, в чем проблема: вы реализуете Hashable неправильно.

Одно важное условие соответствия Hashable состоит в том, что«Равные объекты имеют одинаковые hashValue», что неверно в вашем случае.Как только вы нарушите это фундаментальное предположение, весь код, который зависит от него, вероятно, сломается (например, Dictionary).

В этом примере вы должны либо заставить A работать с идентичностью (в этом случае == будетбыть таким же, как ===), или работать со значениями (в этом случае hashValue будет зависеть только от x и y).

Здесь важно отметить, что Hashableэто не просто означает, что это «значение, которое может создать сам хэш», а фактически является подпротоколом Equatable.Таким образом, это действительно означает «объект, который может быть проверен на равенство, а также может выполнить предварительную проверку на равенство с помощью значения хеша, которое он может произвести».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...