在Rust中是否可能有一组Rc<T>
s(类似于HashSet<Rc<T>>
(,而T
不是Hash
或Ord
?
struct Foo { /* Lots of members, expensive to Hash or Ord */ }
我想在一个集合中有一组Rc<Foo>
引用,以避免重复。我知道HashSet<Rc<T>>
期望T: Hash
,BTreeSet<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
类型实现一个包装器。一个开始的想法是按照你的建议使用地址。您将需要实现Hash
、Eq
和PartialEq
。
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);
}
}
游乐场