gpt4 book ai didi

swift - 如何在 Xcode 9.4 中使 Optionals Hashable

转载 作者:可可西里 更新时间:2023-11-01 01:08:05 26 4
gpt4 key购买 nike

在 Xcode 10 中,Swift 编译器足够智能:

  1. 将包装 Hashable 值的 Optionals 视为 Hashable

  2. Xcode >=9.4 还将处理包含所有 Hashablestruct属性也是 Hashable

奇怪的是,即使构建语言是 Swift 4 甚至 Swift 3,Xcode 10 也会将 Optionals 视为 Hashable。

以下面的代码为例:

struct Foo: Hashable {
var string1: String?
var string2: String?
}

该代码在 Xcode 10 下编译,并且使用 Foo 对象的 hashValue 可以按预期工作,即使构建语言是 Swift 3!

但是,在 Xcode 9.4 中,除非您将属性设为非可选,否则 Foo 结构不会自动 Hashable。

此代码在 Xcode 9.4/Swift 4.1 中的编译和工作方式与您希望的一样:

struct Foo: Hashable {
var string1: String
var string2: String
}

我如何在 Xcode 9 中制作可选项 Hashable?我当然可以自己为我的结构实现 Hashable 一致性,但是为多部分结构创建良好的哈希实际上有点棘手,我想不必担心它。

我也想不出一种直接的方法来制作可选的 Hashable。 (同样,这只是 Xcode < Xcode 10 中的一个问题。我的雇主还没有迁移到 Xcode 10,所以我需要一个适用于 Xcode 9.4 的解决方案)

最佳答案

Swift 4.2 在中定义了条件 Optional: Hashable 一致性 Optional.swift作为

extension Optional: Hashable where Wrapped: Hashable {
// ...
public func hash(into hasher: inout Hasher) {
switch self {
case .none:
hasher.combine(0 as UInt8)
case .some(let wrapped):
hasher.combine(1 as UInt8)
hasher.combine(wrapped)
}
}
}

特别是

  • .none 与整数零具有相同的哈希值,独立于类型,和
  • 哈希值.some(wrapped)是通过混合哈希值得到的用整数 1 包裹

Swift 4.1(随 Xcode 9.4 一起提供)已经有了必要的工具来实现类似的方法:

  • 条件一致性,即我们可以定义一个扩展

    extension Optional: Hashable where Wrapped: Hashable
  • 如果所有成员都是 Hashable,则为类型自动合成 Hashable

这是一个可能的实现:

extension Optional: Hashable where Wrapped: Hashable {
struct Combiner: Hashable {
let left: Int
let right: Wrapped
}

public var hashValue: Int {
switch self {
case .none:
return 0.hashValue
case .some(let wrapped):
return Combiner(left: 1, right: wrapped).hashValue
}
}
}

例子:

struct Foo: Hashable {
var string1: String?
var string2: String?
}

let foo = Foo(string1: "1", string2: "2")
print(foo.hashValue) // 2171695307022640119

为了让这段代码也能在 Swift 4.2 及更新版本中编译,扩展方法可以有条件地编译(比较 SE-0212 Compiler Version Directive ):

#if swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0))
// Code targeting the Swift 4.2 compiler and above:
// Conditional conformance `Optional: Hashable` defined in the standard library.
#elseif swift(>=4.1) || (swift(>=3.3) && !swift(>=4.0))
// Code targeting the Swift 4.1 compiler and above:

extension Optional: Hashable where Wrapped: Hashable {
// ...
}

#endif

关于swift - 如何在 Xcode 9.4 中使 Optionals Hashable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53218315/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com