swift - 将现有的(通用的)swift 类扩展为可哈希的

标签 swift generics

我有一些我想放入字典的类,但是该类不符合 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/

相关文章:

java - 转换为通用原始类。方法运行没有任何异常,如何以及为什么?

generics - 以通用方式操作 Scala 集合

swift - 如何控制 SwiftUI 图像的无障碍画外音文本

ios - 不遵循 QoS 优先级的队列

ios - Apple 的照片应用程序中的过滤器 UIScrollView/UICollectionView 是如何实现的,以至于它打开得如此之快?

swift - allHeaderFields 在查找键时不区分大小写

java - 无法弄清楚如何实例化从具有 <S, T extends S> 等条件的函数返回的泛型类

swift - 键和值具有特定类型的字典类型的扩展

scala - 如何在 Scala 中使用泛型

c# - 根据方法参数构建 IQueryable