Swift 中的可哈希枚举

Sas*_*ine 5 hash enums swift

我想要一个枚举,其中包含两个具有 Hashable 关联类型的案例,每个案例都符合 Hashable,如下所示:

enum WordOrNumber {
    case Word(String)
    case Number(Int)
}
Run Code Online (Sandbox Code Playgroud)

我对散列的第一个想法如下:

extension WordOrNumber: Hashable {
    var hashValue: Int {
        switch self {
            case let .Word(word): 
                return word.hashValue & ~1 // ends in 0
            case let .Number(number):
                return number.hashValue | 1 // ends in 1
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我不确定的是,这将如何与 Swift 的 Dictionary 和 Set 实现中的存储桶交互。

通过 LSB 或 MSB 或中间的某个位置来区分这两种情况会更好吗?

我认为将 hashValues 左移 1 然后加 1 没有任何区别,但我很想知道是否不是这种情况。

编辑:我刚刚对此进行了测试,看起来 Int 的 hashValue 就是值本身。这显然是一个问题,因为您经常会连续获得整数,例如在枚举 Bla: Int {} 中。所以我新的和改进的(?)hashValue 是:

extension WordOrNumber: Hashable {
    var hashValue: Int {
        switch self {
            case let .Word(word): // ends in 0
                return word.hashValue << 1
            case let .Number(number): // ends in 1
                return number.hashValue << 1 &+ 1
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

上面关于 LSB 和 MSB 的问题仍然存在。

eMd*_*dOS 5

有类似的东西:

extension WordOrNumber: Hashable {
    var hashValue: Int {
        switch self {
        case .Word(let value):
            return value.hashValue
        case .Number(let value):
            return value.hashValue
        }
    }

    static func ==(lhs: WordOrNumber, rhs: WordOrNumber) -> Bool {
        switch (lhs, rhs) {
        case (.Word(let lhsValue), .Word(let rhsValue)):
            return lhsValue == rhsValue
        case (.Number(let lhsValue), .Number(let rhsValue)):
            return lhsValue == rhsValue
        default:
            return false
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

……应该够了。