2016-05-16 95 views
2

我想有两个例临床枚举与哈希的相关类型的每个符合哈希的,就像这样:哈希的枚举在斯威夫特

enum WordOrNumber { 
    case Word(String) 
    case Number(Int) 
} 

我对散列的第一个想法是以下几点:

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 
     } 
    } 
} 

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

区分两种情况是由LSB还是MSB,还是在中间的某个位置更好?

我认为它没有任何区别将hashValues左移1,然后加1,或者不,但我会很感兴趣知道是否不是这种情况。

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

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 
     } 
    } 
} 

以上关于LSB和MSB的问题依然存在。

+0

实际上没有必要区分这两种情况。你想达到什么目的? – Sulthan

+0

我不确定你的意思?当然,String和hash的hashValues可能会有冲突,其中.Number(x)== .Word(y),这是有问题的? –

+0

为什么这会有问题?哈希函数并不意味着返回唯一的结果,真正重要的是等式的定义('Equatable',函数'==')。我还会假设'Set'和'Dictionary'都使用辅助哈希函数。 – Sulthan

回答

0

有类似:

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 
     } 
    } 
} 

...应该是足够的。