在项目中,我们正在为模型层使用类,因此我必须编写如下代码:
// MARK: - Hashable
extension Player: Hashable {
static func == (lhs: Player, rhs: Player) -> Bool {
return lhs.hashValue == rhs.hashValue
}
func hash(into hasher: inout Hasher) {
hasher.combine(self.name)
}
}
能否以某种方式避免这种样板文件?默认情况下,是否可以通过 .hashValue
实现 Equatable
比较?谢谢。
最佳答案
这是错误的,编译器自动合成它是没有意义的:
static func == (lhs: Player, rhs: Player) -> Bool {
return lhs.hashValue == rhs.hashValue
}
相同的对象必须具有相同的哈希值,但反之则不然:不同的对象可以具有相同的哈希值。
具体来说,在您的示例中:名称是一个字符串,并且有无限多个不同的字符串,但只有 264 个不同的哈希值。所以一定有两个不同的字符串具有相同的哈希值。
如果所有存储的属性都是Hashable
,那么编译器可以为您完全合成一致性。例如
struct Player : Equatable, Hashable {
let name: String
var score: Int
}
这里如果两个玩家具有相同的名字和相同的分数,则他们是“相同的”。
如果有不可散列的属性,或者如果你想自定义身份的概念那么你必须重写==
和 hash(into)
相应地。散列函数应使用与确定 ==
中的身份相同的属性。例如
struct Player : Equatable, Hashable {
let name: String
var score: Int
static func == (lhs: Player, rhs: Player) -> Bool {
return lhs.name == rhs.name
}
func hash(into hasher: inout Hasher) {
hasher.combine(self.name)
}
}
现在,如果两个玩家的名字相同,则他们是“相同的”。
关于swift - 避免 Equatable 和 Hashable 样板,Swift 4.2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56540092/