Swift 哈希表(Hashable)

在本教程中,我们将通过示例了解 Swift 哈希表(Hashable)。

在 Swift 中,Hashable 是为对象提供 hashValue (哈希值)的协议。hashValue 用于比较两个实例。

要使用 hashValue,我们首先必须将类型(structclass 等)与 Hashable 属性相一致(关联)。例如,

  1. struct Employee: Hashable {
  2. ...
  3. }

在这里,我们将 Employee 结构与 Hashable 协议相一致。

现在,当我们创建 Employee 的实例时,协议将为实例提供哈希值。


实例: Swift 哈希表协议

  1. struct Employee: Hashable {
  2. var name: String
  3. }
  4. let object1 = Employee(name: "Sabby")
  5. let object2 = Employee(name: "Smith")
  6. // print hash values
  7. print(object1.hashValue)
  8. print(object2.hashValue)

结果为:

  1. 754256748862435114
  2. -6408043519205941253

在这里,object1.hashValueobject2.hashValue 分别返回实例 object1object2 的哈希值。

注意:哈希值是一个长整数,它根据您使用的系统而变化,因此对于同一代码,您可能会得到不同的值。

使用哈希协议比较实例

  1. // conform Employee to Hashable
  2. struct Employee: Hashable {
  3. var name: String
  4. var salary: Int
  5. }
  6. // initialize two objects with different property values
  7. let obj1 = Employee(name: "Sabby", salary: 40000)
  8. let obj2 = Employee(name: "Cathy", salary: 30000)
  9. print("Different hash value: ")
  10. print(obj1.hashValue)
  11. print(obj2.hashValue)
  12. // initialize two objects with same property values
  13. let obj3 = Employee(name: "Lanny", salary: 50000)
  14. let obj4 = Employee(name: "Lanny", salary: 50000)
  15. print("\nSame hash value: ")
  16. print(obj3.hashValue)
  17. print(obj4.hashValue)

结果如下:

  1. Different hash value:
  2. 3934953678767833906
  3. 4997634560615333199
  4. Same hash value:
  5. 1588129438168529318
  6. 1588129438168529318

在上面的实例中,我们创建了一个名为 Employee 的结构,它符合 Hashable 协议。

我们已经创建了两个对象 obj1obj2

这一次,obj3obj4 的属性值是相同的,因此我们为实例获得了相同的哈希值。


哈希函数和组合

在上面的示例中,我们比较了结构的所有属性。

然而,有时我们可能需要比较类型的选择特性。在这种情况下,我们可以在类型内使用哈希函数。例如,

  1. func hash(into hasher: inout Hasher) {
  2. hasher.combine(name)
  3. }

这里,hash() 函数使用 hasher.combine() 指定要比较的属性。

使用哈希函数
  1. struct Employee: Hashable {
  2. var name: String
  3. var salary: Int
  4. // create a hash() function to only compare age property
  5. func hash(into hasher: inout Hasher) {
  6. hasher.combine(salary)
  7. }
  8. }
  9. // initialize two objects with different values for salary property
  10. let obj1 = Employee(name: "Sabby", salary: 349879)
  11. let obj2 = Employee(name: "Sabby", salary: 422532)
  12. print(obj1.hashValue)
  13. print(obj2.hashValue)

结果如下:

  1. 3932232896576771782
  2. 743881919875172951

在上面的实例中,我们使用 hash() 函数根据 salary 属性比较了两个实例。

  1. func hash(into hasher: inout Hasher) {
  2. hasher.combine(salary)
  3. }

这里,ob1obj2salary 薪水不同,所以我们得到不同的哈希值。

如果我们在 hash() 函数中使用了 name 属性,我们将得到相同的哈希值。这是因为两个对象的名称相同。

  1. func hash(into hasher: inout Hasher) {
  2. hasher.combine(age)
  3. }
  4. // Output:
  5. // 976332112043722041
  6. // 976332112043722041