已发布 上游基线 bf46254 原文 ↗ 在 GitHub 编辑

Hash

通过高效的哈希来优化相等性检查,从而在哈希集合、哈希映射等集合中实现更快的比较。

Hash 接口与 Equal 接口密切相关,它通过提供一种哈希机制,在优化相等性检查方面扮演辅助角色。哈希是高效判断两个值是否相等的重要步骤,尤其是在与哈希表这类数据结构配合使用时。

Hash 在相等性检查中的角色

Hash 接口的主要目的是提供一种快速且高效的方式,用来判断两个值是否一定不相等,从而对 Equal 接口形成补充。当两个值都实现了 Equal 接口时,会先比较它们的哈希值(通过 Hash 接口计算得出):

  • 哈希值不同:如果哈希值不同,那么可以确定这两个值本身也不同。这一快速检查使系统能够避免一次可能开销很大的相等性比较。
  • 哈希值相同:如果哈希值相同,并不能保证这两个值相等,只能说它们可能相等。在这种情况下,会使用 Equal 接口执行一次更彻底的比较,以确定它们是否真正相等。

这种方式极大地加快了相等性检查的过程,尤其是在那些快速查找和插入至关重要的集合中,例如哈希集合(hash set)或哈希映射(hash map)。

实现 Hash 接口

设想这样一个场景:你有一个自定义的 Person 类,并且希望根据属性判断两个实例是否相等。 通过同时实现 EqualHash 接口,你可以高效地管理这些检查:

示例(为自定义类实现 EqualHash

import { Equal, Hash } from "effect"

class Person implements Equal.Equal {
  constructor(
    readonly id: number, // Unique identifier
    readonly name: string,
    readonly age: number,
  ) {}

  // Define equality based on id, name, and age
  [Equal.symbol](that: Equal.Equal): boolean {
    if (that instanceof Person) {
      return (
        Equal.equals(this.id, that.id) &&
        Equal.equals(this.name, that.name) &&
        Equal.equals(this.age, that.age)
      )
    }
    return false
  }

  // Generate a hash code based on the unique id
  [Hash.symbol](): number {
    return Hash.hash(this.id)
  }
}

const alice = new Person(1, "Alice", 30)
console.log(Equal.equals(alice, new Person(1, "Alice", 30)))
// Output: true

const bob = new Person(2, "Bob", 40)
console.log(Equal.equals(alice, bob))
// Output: false

说明:

  • [Equal.symbol] 方法通过比较 Person 实例的 idnameage 字段来判断相等性。这种方式确保相等性检查是全面的,会考虑所有相关属性。
  • [Hash.symbol] 方法使用这个 person 的 id 计算哈希码。该值用于在哈希操作中快速区分不同实例,从而优化那些使用哈希的数据结构的性能。
  • 当把 alice 与一个属性值完全相同的新 Person 对象比较时,相等性检查返回 true;而把 alicebob 比较时,由于它们的属性值不同,返回 false