Swift Hashable

在 Swift 中,`Hashable` 是一个协议,它为我们的对象提供了一个 `hashValue`。`hashValue` 用于比较两个实例。

要使用 `hashValue`,我们首先必须使类型(struct、class 等)符合(关联)`Hashable` 属性。例如,

struct Employee: Hashable {
  ...
}  

在这里,我们已将 `Employee` 结构体符合 `Hashable` 协议。

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


示例:Swift Hashable 协议

struct Employee: Hashable {
  var name: String
}

let object1 = Employee(name: "Sabby")
let object2 = Employee(name: "Smith")

// print hash values
print(object1.hashValue)
print(object2.hashValue)

输出

754256748862435114
-6408043519205941253

在这里,`object1.hashValue` 和 `object2.hashValue` 分别返回实例 `object1` 和 `object2` 的哈希值。

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


使用 Hashable 协议比较实例

// conform Employee to Hashable
struct Employee: Hashable {
    
    var name: String
    var salary: Int
}

// initialize two objects with different property values 
let obj1 = Employee(name: "Sabby", salary: 40000)
let obj2 = Employee(name: "Cathy", salary: 30000)

print("Different hash value: ")
print(obj1.hashValue)
print(obj2.hashValue)

// initialize two objects with same property values 
let obj3 = Employee(name: "Lanny", salary: 50000)
let obj4 = Employee(name: "Lanny", salary: 50000)

print("\nSame hash value: ")
print(obj3.hashValue)
print(obj4.hashValue)

输出

Different hash value: 
3934953678767833906
4997634560615333199

Same hash value: 
1588129438168529318
1588129438168529318

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

我们创建了两个对象 `obj1` 和 `obj2`。

let obj1 = Employee(name: "Sabby", salary: 40000)
let obj2 = Employee(name: "Cathy", salary: 30000)

在这里,这两个实例的 `name` 和 `salary` 属性的值都不同。这就是为什么 `obj1` 和 `obj2` 的哈希值不同的原因。

同样,我们创建了另外两个对象。

let obj3 = Employee(name: "Lanny", salary: 50000)
let obj4 = Employee(name: "Lanny", salary: 50000)

这次 `obj3` 和 `obj4` 的属性值相同,因此我们为这两个实例获得了相同的哈希值。


哈希函数和 Combine

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

但是,有时我们可能只想比较类型的特定属性。在这种情况下,我们可以在类型中使用哈希函数。例如,

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

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


哈希函数的使用

struct Employee: Hashable {
  
 var name: String
 var salary: Int

 // create a hash() function to only compare  age property        
 func hash(into hasher: inout Hasher) {
   hasher.combine(salary)
 }

}

// initialize two objects with different values for salary property
let obj1 = Employee(name: "Sabby", salary: 349879)
let obj2 = Employee(name: "Sabby", salary: 422532)

print(obj1.hashValue)
print(obj2.hashValue)

输出

3932232896576771782
743881919875172951

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

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

在这里,`ob1` 和 `obj2` 的薪资不同,因此我们获得了不同的哈希值。

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

func hash(into hasher: inout Hasher) { 
  hasher.combine(age)
}

// Output:
// 976332112043722041
// 976332112043722041
你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战