Swift中的哈希协议

昨天我进行了一次关于集合的讨论,并提出了符合可哈希协议的类型的想法。 不久之后,我意识到我对可哈希协议的理解是有限的,因此我开始将我确实知道的信息拼凑在一起。 我知道一个协议类似于一个蓝图,因为它列出了一个人必须采取并遵守的职责。 我还知道,集合在无序集合中存储了相同类型的不同值。 我的猜测是,当我们在集合中使用自定义类型时,它必须符合可哈希协议,这意味着要被视为可哈希对象,需要满足许多要求。 无论哪种方式,我都无法深入了解可哈希协议的实际含义或它们在自定义类型中的使用方式,因此我开始进行一些调查。

我浏览了Apple的文档,试图弄清楚什么是可哈希协议,并希望能更全面地了解为什么在集合中使用它们。

苹果将hashable定义为“一种为整数提供哈希值的类型。”好吧,但是什么是哈希值?-通过进一步阅读,我发现哈希值由类型的hashValue属性提供,并且基本上是一个整数,即对于相等比较的任何两个实例,都是相同的。

综上所述, hashValue是具有以整数形式存在的hashValue的类型,可以在不同类型之间进行比较。

举例来说,我们有两个实例ab 。 如果a == b ,则a.hashValue == b.hashValue ,但是具有相同hashValue两个实例并不总是相等的。

当我们遵守可散列协议时,我们还必须遵守平等协议,但是让我们一次采取这一步骤。

我们遵循可哈希协议,就像我们执行其他任何协议一样:

 狗类:可哈希{ 
  var uid:整数 
变量名称:字符串
变量年龄:整数
  init(uid:Int,name:String,age:Int){ 
self.uid = uid
self.name =名称
自我年龄=年龄
}
}

但是,当我们遵循可hashValue协议时,我们必须具有hashValue属性。

 狗类:可哈希{ 
  var uid:整数 
变量名称:字符串
变量年龄:整数
var hashValue:Int {
返回uid.hashValue
}
  init(uid,Int,name:String,age:Int){ 
self.uid = uid
self.name =名称
自我年龄=年龄
}
}

如果我们以这种方式离开我们的代码,您会注意到一个错误: “类型’Dog’不符合协议’Equatable’。”

尽管我们符合Hashable ,但Hashable也必须符合Equatable 。 苹果将Equatable定义为可以比较值相等性的类型,如果我们记得,它是可哈希协议的工作定义的一部分。

为了符合Equatable我们必须添加一个比较类型并检查它们是否相等的函数。

 静态函数==(lhs:Dog,rhs:Dog)-> Bool { 
返回lhs.uid == rhs.uid
}

就像这样,我们也可以开始将自定义类型用作字典或集合中元素的键值!

 让dog1 =狗(uid:1,名称:“ Scrappy”,年龄:4) 
让dog2 =狗(uid:2,名称:“ Sparky”,年龄:3)
  var dogArray:[Dog:String] = [ 
dog1:“ Woff Woff”,
dog2:“哇!”
]
  var dogs:Set  = [dog1,dog2] 

您还将注意到,我们比较了每个实例的hashValue ,尽管它们的类型相同,但它们是不同的。

 打印(dog2.hashValue) 
打印(dog1.hashValue)
  //打印4792065050360486817 
//打印8918364877838387272