一个人如何创造出一套铁 rust ?是否有必要为满足HashSet<HashSet<_>>的每种混凝土类型写一个impl块?

最简单的失败例子:

fn main () {
    let a: HashSet<u32> = HashSet::new();
    let c: HashSet<HashSet<u32>> = HashSet::new();
    c.insert(a);
}

错误:

"insert" method cannot be called on `std::collections::HashSet<std::collections::HashSet<u32>>` due to unsatisfied trait bounds
HashSet doesn't satisfy `std::collections::HashSet<u32>: Hash

有没有可能推翻哈塞特不幸的事实?我想使用散列集,需要我的内容通过实际(内存)相等来唯一;我不需要根据内容来区分.

推荐答案

我希望有一组集合,并希望它们通过"实际"(内存)相等而不是内容来唯一.

为此,首先需要对哈希集进行装箱,使其具有稳定的内存地址.例如:

struct Set<T>(Box<HashSet<T>>);

要使Set可散列,需要实现HashEq:

impl<T> Set<T> {
    fn as_addr(&self) -> usize {
        // as_ref() gives the reference to the heap-allocated contents
        // inside the Box, which is stable; convert that reference to a
        // pointer and then to usize, and use it for hashing and equality.
        self.0.as_ref() as *const _ as usize
    }
}

impl<T> Hash for Set<T> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.as_addr().hash(state);
    }
}

impl<T> Eq for Set<T> {}

impl<T> PartialEq for Set<T> {
    fn eq(&self, other: &Self) -> bool {
        self.as_addr() == other.as_addr()
    }
}

最后,需要添加一些类似集合的方法和构造函数以使其可用:

impl<T: Hash + Eq> Set<T> {
    pub fn new() -> Self {
        Set(Box::new(HashSet::new()))
    }

    pub fn insert(&mut self, value: T) {
        self.0.insert(value);
    }

    pub fn contains(&mut self, value: &T) -> bool {
        self.0.contains(value)
    }
}

现在,您的代码将正常工作,并额外使用Rc,这样您就可以在插入原始Set后进行查找:

fn main() {
    let mut a: Set<u32> = Set::new();
    a.insert(1);
    let a = Rc::new(a);
    let mut c: HashSet<_> = HashSet::new();
    c.insert(Rc::clone(&a));
    assert!(c.contains(&a));
}

Playground

Rust相关问答推荐

无需通过ASIO输入音频,并使用cpal进行反馈示例

如何在不安全的代码中初始化枚举 struct

有没有办法指定只在Rust的测试中有效的断言?

交换引用时的生命周期

如何模拟/创建ReqData以测试Actix Web请求处理程序?

在复制类型中使用std::ptr::WRITE_VILAR进行内部可变性的安全性(即没有UnSafeCell)

为什么HashMap::get和HashMap::entry使用不同类型的密钥?

在 Rust 中,为什么 10 个字符的字符串的 size_of_val() 返回 24 个字节?

在 Rust 中,是否可以定义一个需要实现类型的构造函数的对象安全特征?

如何在 Rust 中将函数项变成函数指针

在Rust中实现Trie数据 struct 的更好方式

‘&T as *const T as *mut T’ 在 ‘static mut’ 项目中合适吗?

如何为已实现其他相关 std trait 的每个类型实现一个 std Trait

为什么需要同时为值和引用实现`From`?方法不应该自动解引用或borrow 吗?(2023-06-16)

在线程中运行时,TCPListener(服务器)在 ip 列表中的服务器实例之前没有从客户端接受所有客户端的请求

返回引用字符串的future

深度嵌套枚举的清洁匹配臂

有没有更好的方法来为拥有 DIsplay 事物集合的 struct 实现 Display?

Rustfmt 是否有明确类型的选项?

返回 &str 但不是 String 时,borrow 时间比预期长