Swift 基础

Swift Hashable 和 Equatable

2020-07-27  本文已影响0人  幸运者_Lucky

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 值可看出.

上一篇下一篇

猜你喜欢

热点阅读