Swift中的hash和hashValue之间的区别

35

在 Swift 中,Hashable 协议要求您实现一个名为 hashValue 的属性:

protocol Hashable : Equatable {
    /// Returns the hash value.  The hash value is not guaranteed to be stable
    /// across different invocations of the same program.  Do not persist the hash
    /// value across program runs.
    ///
    /// The value of `hashValue` property must be consistent with the equality
    /// comparison: if two values compare equal, they must have equal hash
    /// values.
    var hashValue: Int { get }
}

然而,似乎还有一个名为hash的类似属性。

hashhashValue之间有什么区别?


3
hashNSObject 协议的一个属性,详情请参考NSObject protocol。在 Swift 中的 NSObject 子类里,需要注意使用 hash 而不是 hashValue,以及 isEqual 而不是 ==,具体可参考NSObject subclass in Swift: hash vs hashValue, isEqual vs == - Martin R
1个回答

40

hashNSObject协议的必需属性,其中包含对于所有Objective-C对象都至关重要的方法。因此它早于Swift。 默认实现只返回对象地址, 如可以在NSObject.mm中看到,但可以在NSObject子类中覆盖该属性。

hashValue是Swift Hashable协议的必需属性。

两者通过在Swift标准库中定义的NSObject扩展连接,位于 ObjectiveC.swift中:

extension NSObject : Equatable, Hashable {
  /// The hash value.
  ///
  /// **Axiom:** `x == y` implies `x.hashValue == y.hashValue`
  ///
  /// - Note: the hash value is not guaranteed to be stable across
  ///   different invocations of the same program.  Do not persist the
  ///   hash value across program runs.
  open var hashValue: Int {
    return hash
  }
}

public func == (lhs: NSObject, rhs: NSObject) -> Bool {
  return lhs.isEqual(rhs)
}

(关于open var的含义,请参阅什么是Swift中的'open'关键字?)

因此,NSObject(和所有子类)符合Hashable协议, 并且默认的hashValue实现返回对象的hash属性。

NSObject协议的isEqual方法和Equatable 协议的==运算符之间存在类似的关系: NSObject(和所有子类)符合Equatable协议, 并且默认的==实现会在操作数上调用isEqual:方法。


1
不要在程序运行中保持哈希值。知道这个就好了,刚浪费了2个小时纠结为什么我的保留的哈希值不一样。 - quemeful
1
@quemeful:它总是被记录为非持久的,但是只有在Swift 4.2中,使用每次执行的随机种子来积极执行Swift库,参见https://github.com/apple/swift-evolution/blob/master/proposals/0206-hashable-enhancements.md#the-hasher-struct。 - Martin R
1
似乎 hash 是持久的(至少在 Objective-C 中使用),而 hashValue 不是。 - Declan McKenna
2
@DeclanMcKenna:对于“NSObject”子类,“hashValue”和“hash”应该返回相同的值(即内存地址),除非在子类中进行了重写。这个内存地址可以在程序的多次运行中是相同的,但是你不能依赖它。 - Martin R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接