在 Swift 中实现哈希组合器



我正在扩展符合Hashablestruct。我将使用 DJB2 哈希组合器来完成此操作。

为了便于为其他事情编写哈希函数,我想扩展Hashable协议,以便我的哈希函数可以像这样编写:

extension MyStruct: Hashable {
public var hashValue: Int {
return property1.combineHash(with: property2).combineHash(with: property3)
}
}

但是当我尝试将扩展写入实现'combineHash(with:)的Hashable时,如下所示:

extension Hashable {
func combineHash(with hashableOther:Hashable) -> Int {
let ownHash = self.hashValue
let otherHash = hashableOther.hashValue
return (ownHash << 5) &+ ownHash &+ otherHash
}
}

。然后我得到这个编译错误:

/Users/benjohn/Code/Nice/nice/nice/CombineHash.swift:12:43:协议"Hashable"只能用作泛型约束,因为它具有 Self 或关联的类型要求

这是 Swift 不会让我做的事情,还是我只是做错了并收到无用的错误消息?


除了JAL 的评论链接到 swift 哈希函数的代码审查,该代码审查也是由 Martin 编写的,他在下面提供了公认的答案!他在讨论中提到了一个不同的哈希组合器,它基于 c++ boost 库中的一个。讨论确实值得一读。替代合路器的碰撞较少(根据测试的数据)。

使用 Apple 开发人员文档中hash(into:)的方法:

https://developer.apple.com/documentation/swift/hashable

struct GridPoint {
var x: Int
var y: Int
}
extension GridPoint: Hashable {
static func == (lhs: GridPoint, rhs: GridPoint) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
func hash(into hasher: inout Hasher) {
hasher.combine(x)
hasher.combine(y)
}
}

如果P,则不能定义类型为P的参数 是具有Self或相关类型要求的协议。 在这种情况下,它是Equatable协议,Hashable继承,具有Self要求:

public static func ==(lhs: Self, rhs: Self) -> Bool

您可以做的是定义一个泛型方法:

extension Hashable {
func combineHash<T: Hashable>(with hashableOther: T) -> Int {
let ownHash = self.hashValue
let otherHash = hashableOther.hashValue
return (ownHash << 5) &+ ownHash &+ otherHash
}
}

最新更新