我有一些我想放入字典的类,但是该类不符合 Hashable,我不能将它用作 Swift 字典中的键。因为它是一个类,所以它可以通过它在内存中的位置来识别并且我很乐意使用它的标识符,无论如何类型本身不属于值语义世界。
因此我声明了一个扩展来实现它
extension SomeGenericType : Hashable {
public var hashValue: Int {
return unsafeAddressOf(self).hashValue
}
}
这似乎没问题,但是 Hashable 继承自 Equatable,所以我也需要实现它,这是我的第一次尝试:
public func ==(lhs: SomeGenericType, rhs: SomeGenericType) -> Bool {
return unsafeAddressOf(lhs) == unsafeAddressOf(rhs)
}
错误
"Reference to generic type 'SomeGenericType' requires arguments in <...>"
...很公平,让我们开始吧
public func ==<T : SomeGenericType >(lhs: T, rhs: T) -> Bool {
return unsafeAddressOf(lhs) == unsafeAddressOf(rhs)
}
现在它说
"Reference to generic type 'SomeGenericType' requires arguments in <...>"
嗯,所以我可以为所有 SomeGenericType 工作,不管它得到什么类型。也许我们可以把 AnyObject 放在那里?
public func ==<T : SomeGenericType<AnyObject>>(lhs: T, rhs: T) -> Bool {
return unsafeAddressOf(lhs) == unsafeAddressOf(rhs)
}
好的,现在 == 很高兴,但显然我没有正确实现 Hashable,因为现在我的 hashable 扩展上有一个错误说:
"Type 'SomeGenericType<T>' does not conform to protocol 'Equatable'"
我试过在 SomeGenericType 上摆弄一个受限扩展,但我似乎无法使一个类型的受限扩展采用另一种协议(protocol),语言语法似乎不允许这样做,所以我在这里有点困惑
编辑,供引用 SomeGenericType定义如下:
class SomeGenericType<T> {
}
最佳答案
正确的语法是
public func ==<T>(lhs: SomeGenericType<T>, rhs: SomeGenericType<T>) -> Bool {
return unsafeAddressOf(lhs) == unsafeAddressOf(rhs)
}
操作数需要是 SomeGenericType
的实例
相同类型的占位符T
。
对于 Swift 3,使用 ObjectIdentifier
而不是 unsafeAddressOf
。
关于swift - 将现有的(通用的)swift 类扩展为可哈希的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33189018/