Rc 集,<T>其中 T 不是哈希或 Ord?

  • 本文关键字:哈希 Ord Rc 其中 rust
  • 更新时间 :
  • 英文 :


在Rust中是否可能有一组Rc<T>s(类似于HashSet<Rc<T>>(,而T不是HashOrd

struct Foo { /* Lots of members, expensive to Hash or Ord */ }

我想在一个集合中有一组Rc<Foo>引用,以避免重复。我知道HashSet<Rc<T>>期望T: HashBTreeSet<Rc<T>>期望T: Ord:

let mut hash_set = HashSet::<Foo>::new();
hash_set.insert(Foo {}); // error[E0599]: trait bounds were not satisfied
let mut tree_set = BTreeSet::<Foo>::new(); // error[E0277]: trait bound `Foo: Ord` is not satisfied
tree_set.insert(Foo {});

但我不想通过Foo对象的值进行比较,我希望该集通过Rc引用进行比较。我的理解是,如果我更改底层Foo对象的值,Rc仍然指向相同的堆地址。因此,堆地址可以用作哈希或排序的基础,这正是我想要的。

Rust的std有可能吗?或者一些板条箱?还是我对Rc的理解不正确?

您可以为Rc类型实现一个包装器。一个开始的想法是按照你的建议使用地址。您将需要实现HashEqPartialEq

use std::hash::Hash;
struct Foo {}
struct RcHashFoo(Rc<Foo>);
impl PartialEq for RcHashFoo {
fn eq(&self, other: &RcHashFoo) -> bool {
Rc::ptr_eq(&self.0, &other.0)
}
}
impl Eq for RcHashFoo {}
impl Hash for RcHashFoo {
fn hash<H>(&self, hasher: &mut H) where H: Hasher { 
hasher.write_usize(Rc::as_ptr(&self.0) as usize);
}
}

游乐场

最新更新