Swift-无法获取从类扩展的字典类的值

时间:2018-10-13 10:22:28

标签: swift

简单的问题,但我不知道为什么!

  • 创建一个类-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 {

}

用于获取收藏价值的功能检查-hm。

     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”-> 在馆藏内未找到a2 嗯?

对于比较2个对象,我使用:(lhs.x == rhs.x && lhs.y == rhs.y)。 (如果使用ObjectIdentifier,则比较结果始终为false)

谢谢您的解释。

enter image description here

2 个答案:

答案 0 :(得分:0)

我不知道为什么它的行为确实如此,但是我可以说出问题所在:您实施的Hashable错误。

符合Hashable的一个重要条件是“相等的对象具有相同的hashValue”,这在您的情况下是不正确的。一旦打破了这一基本假设,所有依赖于此的代码都可能会崩溃(例如Dictionary)。

在此示例中,您应该使A处理身份(在这种情况下=====相同),或者处理值(在这种情况下{{1 }}仅取决于hashValuex)。

这里要注意的重要一点是y不仅意味着“它是一个可以产生自身哈希值的值”,而且实际上是Hashable的子协议。因此,它的真正含义是“可以检查是否相等的对象,还可以使用它可以产生的哈希值进行初步的相等性检查”。

答案 1 :(得分:0)

删除hashValue的实现,并替换为插入:

func hash(into hasher: inout Hasher) {
    x.hash(into:&hasher)
    y.hash(into:&hasher)
}