我有一些我想要放入字典的类但是该类不符合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,因为我的可扩展扩展程序现在出现错误:
"Type 'SomeGenericType<T>' does not conform to protocol 'Equatable'"
我试过摆弄SomeGenericType上的约束扩展,但我似乎无法使一个类型的约束扩展采用另一种协议,语言语法似乎不允许它,所以我在这里有点腌渍
编辑,供参考SomeGenericType定义如下:
class SomeGenericType<T> {
}
答案 0 :(得分:4)
正确的语法是
public func ==<T>(lhs: SomeGenericType<T>, rhs: SomeGenericType<T>) -> Bool {
return unsafeAddressOf(lhs) == unsafeAddressOf(rhs)
}
操作数需要是SomeGenericType
的实例
相同的类型占位符T
。
对于 Swift 3,使用ObjectIdentifier
代替unsafeAddressOf
。
答案 1 :(得分:0)
这是一个较旧的问题,但我最近遇到了类似的问题,除了我有一个struct
。
您可能希望实现4种不同的中缀运算符函数:
// #1
public func ==<T>(lhs: SomeGenericType<T>, rhs: SomeGenericType<T>) -> Bool {
return lhs === rhs // it's a class right - check the reference
}
// #2
public func !=<T>(lhs: SomeGenericType<T>, rhs: SomeGenericType<T>) -> Bool {
return !(lhs === rhs)
}
// #3
public func ==<T, U>(lhs: SomeGenericType<T>, rhs: SomeGenericType<U>) -> Bool {
return lhs.hashValue == rhs.hashValue
}
// #4
public func !=<T, U>(lhs: SomeGenericType<T>, rhs: SomeGenericType<U>) -> Bool {
return lhs.hashValue != rhs.hashValue
}
问题解决了吗?程序应使用这些而不是stdlib中的通用函数。
您还可以通过hashValue
检查所有内容。 ;)