美文网首页Swift 基础
Swift Hashable 和 Equatable

Swift Hashable 和 Equatable

作者: 幸运者_Lucky | 来源:发表于2020-07-27 17:52 被阅读0次

    Hashable 和 Equatable

    Swift provides a synthesized implementation of Hashable for the following kinds of custom types:

    1. Structures that have only stored properties that conform to the Hashable protocol
    2. Enumerations that have only associated types that conform to the Hashable protocol
    3. Enumerations that have no associated types

    先看官方说明,

    1. struct 中的属性都实现了 Hashable
    2. 枚举中的泛型必须实现了 Hashable
    3. 枚举中无泛型
      以上三种情况, Swift 默认提供了统一 hash 方案
      下面是一个 struct 的例子, enum 同理:
    struct A: Hashable {
        var a = 0
        var b = 0
        var c = 0
    }
    
    let a = A()
    var b = A()
    
    if a == b {
        print("1 equal")
    }
    
    b.a = 10
    if a == b {
        print("2 equal")
    }
    
    b.a = 0
    if a == b {
        print("3 equal")
    }
    
    //print
    1 equal
    3 equal
    

    如果 struct 中属性有没实现 Hashable, enum 的泛型没 conform Hashable,
    class 如何实现 Hashable?

    Swift provides a synthesized implementation of Equatable for the following kinds of custom types:

    Structures that have only stored properties that conform to the Equatable protocol
    Enumerations that have only associated types that conform to the Equatable protocol
    Enumerations that have no associated types

    官方说明,

    1. struct 中的属性都实现了 Equatable
    2. 枚举中的泛型必须实现了 Equatable
    3. 枚举中无泛型
      以上三种情况, Swift 默认提供了统一 hash 方案, 同上面的 Hashable

    首先 Hashable 实现了 Equatable, 所以实现了 Hashable, 就肯定实现了 Equatable
    ==, 比如 Swift 中 Int, String, Array ...都实现了 Hashable, NSObject 也实现了, 但自定义的 struct, enum, class 都需要自己来实现 Hashable 或者 Equatable,

    struct AA {
        
    }
    
    struct A: Hashable {
        static func == (lhs: A, rhs: A) -> Bool {
            return lhs.hashValue == rhs.hashValue
        }
        
        func hash(into hasher: inout Hasher) {
            print("hash run")
            hasher.combine(100)
            hasher.finalize()
        }
        
        var a = 0
        var b = 0
        var c = 0
        
        var d = AA()
    }
    

    如上代码, AA 没有实现 Hashable, A 中包含 AA 的属性, 所以 AA, 默认实现 Hashable 和 Equatable 都失效了.

    1. 需要实现 == 方法
    2. 需要实现 func hash(into hasher: inout Hasher) 方法
      看源码, 发现 hash 值是通过 Hasher 这个结构体类型来计算的,
      它有个 combine 方法来拼接一些实现了 Hashable 的参数, 通过 finalize() 方法来获取拼接完成的 hash 值.
    var hasher2 = Hasher()
    hasher2.combine(100)
    print(hasher2.finalize())
    
    print(a.hashValue)
    7835368441742582953
    hash run
    7835368441742582953
    // print
    
    

    我们发现, hashValue 这个属性会通过调用 func hash(into hasher: inout Hasher) 这个方法来获取值, 根据比较 hash 值可看出.

    相关文章

      网友评论

        本文标题:Swift Hashable 和 Equatable

        本文链接:https://www.haomeiwen.com/subject/jiqtrktx.html