一尘不染

即使使用相同的快速版本,Xcode 9和Xcode 10也会给出不同的结果

swift

我在xcode 9.3和xcode 10 beta 3操场上都运行此代码

import Foundation

public protocol EnumCollection: Hashable {
    static func cases() -> AnySequence<Self>
}

public extension EnumCollection {

    public static func cases() -> AnySequence<Self> {
        return AnySequence { () -> AnyIterator<Self> in
            var raw = 0
            return AnyIterator {
                let current: Self = withUnsafePointer(to: &raw) { $0.withMemoryRebound(to: self, capacity: 1) { $0.pointee } }

                guard current.hashValue == raw else {
                    return nil
                }

                raw += 1
                return current
            }
        }
    }
}

enum NumberEnum: EnumCollection{
    case one, two, three, four
}

Array(NumberEnum.cases()).count

即使两者都使用Swift 4.1,但它们却给了我不同的结果

xcode 9.3 上,数组的大小为 4

xcode 10 beta 3 上,数组的大小为 0

我一点都不明白。


阅读 190

收藏
2020-07-07

共1个答案

一尘不染

这是获取所有枚举值序列的一种未公开的方法,并且仅在偶然的早期Swift版本中才起作用。它依赖于枚举值的哈希值是从零开始的连续整数。

对于Swift 4.2(即使在Swift 4兼容模式下运行),这绝对不再起作用,因为哈希值现在始终是随机的,请参阅SE-0206 Hashable
Enhancements

为了使散列值难以预测,默认情况下,标准散列函数使用每个执行的随机种子。

您可以使用

print(NumberEnum.one.hashValue)
print(NumberEnum.two.hashValue)

这不会 打印01在Xcode 10,但一些其他值这也与每个程序运行而有所不同。

extension NumberEnum: CaseIterable  { }
print(Array(NumberEnum.allCases).count) // 4
2020-07-07