swift自定义值类型做字典的key注意!!!

应该都知道,swift的字典key只要实现Hashable协议就都可以做为key使用了(不知道的可以command进去看一下),我主要是介绍一下在我自定义key实现hashable的坑。
  • hash值计算的时间复杂度
  • 异或运算结果误差

hash值计算的时间复杂度

public protocol Hashable : Equatable {

    /// The hash value.
    ///
    /// Hash values are not guaranteed to be equal across different executions of
    /// your program. Do not save hash values to use during a future execution.
    public var hashValue: Int { get }
}

我们需要返回的hashValue。 返回值Int->对应我们自定义的值类型的hash值

当我们每次去获取dictionary的时候,都会走上面 public var hashValue: Int { get }闭包

那么我们去读字典的操作时间复杂度=闭包里面的时间复杂度
如果闭包里面有消耗性能的O(n)计算,那访问字典就比较消耗性能了

异或运算结果误差

写放一个我写的例子

struct Account {
    var age: Int
    var height: Float
}

extension Account: Hashable,Equatable {
    var hashValue: Int {
        return age.hashValue ^
            height.hashValue
        
    }
    
    static func ==(lhs: Account, rhs: Account) -> Bool {
        return lhs.age == rhs.age &&
            lhs.height == rhs.height
    }

}

 var account1 = Account(age: 18, height: 180)

一般我们通过异或运算进行一些低消耗的运算。但是我们知道a ^ b是等于b ^ a的,也就是如果Account里面俩个属性的值颠倒过来,那么account1的hash值其实是不变的

算是愚见了,分享出来,希望大家多指点。自己可以多学习!
最后我们一般是尽可能的避免使用引用类型作为key,这通常会给你带来不必要的麻烦。当我们使用引用类型作为key之后,引用类型的对象在Dictionary之外被修改的时候,Key的内容也会随之修改。key对应的哈希值是改变的,这样就无法获得对应的value了。

你可能感兴趣的:(swift自定义值类型做字典的key注意!!!)