对 Hashable 的条件一致性

Conditional Conformance to Hashable

对于 Xcode 10 和 Swift 4.2,还有其他类型符合 Hashable,只要它们的元素也符合 HashableArray, 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 的警告静音?

条件编译语句 #if swift(...) 检查 语言版本 你是 运行 – .

在您的情况下,听起来您正在 Swift 4 兼容模式下使用 Swift 4.2 编译器,这为您提供了 。因此,这通过了条件编译语句,并且您的扩展被编译,为您提供了重复的一致性。

为了检查低于 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, which is available in Swift 4.2 from Xcode 10 beta 4 onwards ( 的情况会好很多)。有了它,您可以直接测试编译器版本,忽略它可能在 运行 中的任何兼容模式。

这对您的具体情况没有帮助,因为您需要 Swift 4.2 和 4.1 编译器都能理解代码(正如 Martin 也指出的那样),但对于未来的兼容性问题,您可以示例 使用 #if !compiler(>=5) 以便仅在使用 4.2 编译器时编译代码块。