rust - 有没有办法为特定的 HashSet 或 HashMap 覆盖类型的相等性和哈希函数?

标签 rust hashmap hashset

我有一个 User 结构:

struct User {
    id: i32,
    email: String,
    // ...
}

在我的代码的一部分中,我想通过数据库 ID 获取唯一用户,但在另一段代码中,我想通过电子邮件地址获取唯一用户。我曾在系统上工作过,用户使用 LDAP CN、电子邮件等映射到外部系统帐户,并且在某些情况下能够通过不同的 ID 映射用户非常有用。

在 .NET 中,您可以传入一个 IEqualityComparer。为特定的 Dictionary 覆盖 equals/hash 的接口(interface)。在 C++ 中,unordered_map类具有散列和 eq 函数的通用参数。在 Java 中,当我想获得唯一值时,我学会了只使用 Map 而不是 Set,但这可能很尴尬,尤其是对于复合键。

老实说,这是一种非常罕见的情况,总有使用映射而不是集合或使用自己的 Hash/Eq 创建包装器结构的解决方法impl block 。我只是好奇在 Rust 中是否有一种我还不知道的更简单的方法来做到这一点。

最佳答案

使用一个或多个newtypes具有您想要的相等性和散列的特定定义:

use std::hash::{Hash, Hasher};

struct ById(User);

impl Hash for ById {
    fn hash<H>(&self, h: &mut H)
    where
        H: Hasher,
    {
        self.0.id.hash(h)
    }
}

impl PartialEq for ById {
    fn eq(&self, other: &Self) -> bool {
        self.0.id == other.0.id
    }
}

impl Eq for ById {}
fn example(k: User, v: i32) {
    let mut h = std::collections::HashMap::new();
    h.insert(ById(k), v);
}

Do I need to use .0 to get at the underlying User when I pull ByIds out of the map?

是的。

Is there any magic to implicitly convert to the underlying User?

没有。

I might be better off implementing Deref or something.

Is it considered a bad practice to implement Deref for newtypes?

另见:

关于rust - 有没有办法为特定的 HashSet 或 HashMap 覆盖类型的相等性和哈希函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65671746/

相关文章:

rust - Result<usize, std::io::error::Error> 在 Rust 1.0.0 中没有实现 expect

hashmap - Kotlin HashMap 使用数组包含键

java - 如何访问 HashMap 内对象的值

java - 在 Java 中将哈希集保存到文件中

java - HashSet 中元素的顺序是如何工作的?

java - 无法将元素添加到哈希集的顶部

rust - 有没有办法传递对泛型函数的引用并返回与参数的生命周期无关的 impl Trait?

rust - 为什么通过指向移动变量的指针写入在 Rust 中没有被确定为 UB?

types - 什么时候将数字文字分配给默认类型?

java - HashMap的键和值