对于Xcode 10和Swift 4.2,还有其他符合Hashable
的类型,只要它们的元素也符合Hashable
(Array
,Dictionary
等)即可
我目前在我的项目中有一些代码可以为Swift 4.1及以下版本添加Hashable
一致性,
extension Array: Hashable where Element: Hashable {
public var hashValue: Int {
let prime = 31
var result = 1
for element in self {
result = prime * result + element.hashValue
}
return result
}
}
但是,即使我在代码周围添加#if !swift(>=4.2)
,我仍然在Xcode中看到相同的警告。
我的问题是,如何在Swift 4.1及更低版本的条件下保持对Hashable
的条件符合性,而对Swift 4.2保持警告状态呢?
答案 0 :(得分:3)
条件编译语句#if swift(...)
会与您运行的语言版本相对应-can differ from the compiler (and therefore standard library) version。
在您的情况下,听起来好像您正在以Swift 4兼容模式使用Swift 4.2编译器,这为您提供了language version of 4.1.50。因此,这将传递条件编译语句,并且将对您的扩展进行编译,从而为您提供重复的一致性。
要检查低于4.2的编译器版本,您需要执行以下操作:
// less than 4.2 in Swift 4 compat mode and (less than 4.2 in 3 compat mode or
// greater than 4).
#if !swift(>=4.1.50) && (!swift(>=3.4) || swift(>=4.0))
extension Array : Hashable where Element : Hashable {
public var hashValue: Int {
let prime = 31
var result = 1
for element in self {
result = prime * result + element.hashValue
}
return result
}
}
#endif
使用the new #if compiler
directive可以使事情变得更好,它可以从Xcode 10 beta 4起(confirmed by @MartinR)在Swift 4.2中获得。这样,您就可以直接测试编译器版本,而无需考虑其可能在其中运行的任何兼容模式。
这对您的特定情况没有帮助,因为您需要Swift 4.2和4.1编译器都可以理解代码(正如Martin所指出的),但是对于将来的兼容性问题,您可以使用{{1} },以便仅在使用4.2编译器的情况下编译代码块。