HiD*_*der 3 hashmap hashset rust
我有一个结构,除其他数据外,还有一个唯一的id:
struct Foo {
id: u32,
other_data: u32,
}
Run Code Online (Sandbox Code Playgroud)
我想使用id键作为键并将其保留在结构中:
use std::collections::HashSet;
use std::hash::{Hash, Hasher};
impl PartialEq for Foo {
fn eq(&self, other: &Foo) -> bool {
self.id == other.id
}
}
impl Eq for Foo {}
impl Hash for Foo {
fn hash<H: Hasher>(&self, state: &mut H) {
self.id.hash(state);
}
}
Run Code Online (Sandbox Code Playgroud)
这有效:
pub fn bar() {
let mut baz: HashSet<Foo> = HashSet::new();
baz.insert(Foo {
id: 1,
other_data: 2,
});
let other_data = baz.get(&Foo {
id: 1,
other_data: 0,
}).unwrap()
.other_data;
println!("other_data: {}", other_data);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法写baz.get(1).unwrap().other_data;而不是baz.get(&Foo { id: 1, other_data: 0 }).unwrap().other_data;?
替代方案可能是HashMap密钥包含在内部的位置struct.但是,我不能拥有id结构内部和id用于的重复key.
当您签出签名时HashSet::get,您会注意到它比您预期的要复杂一些:
fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T>
where
T: Borrow<Q>,
Q: Hash + Eq,
Run Code Online (Sandbox Code Playgroud)
这样做恰好可以解决您的问题.get接受对&Q可以从set(T: Borrow<Q>)中的类型借用的任何类型()的引用.T应该被理解为"我的类型",Q应该被理解为"查询类型".
因此,您需要Borrow为您的类型实现:
use std::borrow::Borrow;
use std::collections::HashSet;
use std::hash::{Hash, Hasher};
type Id = u32;
#[derive(Debug, Eq)]
struct Foo {
id: Id,
other_data: u32,
}
impl PartialEq for Foo {
fn eq(&self, other: &Foo) -> bool {
self.id == other.id
}
}
impl Hash for Foo {
fn hash<H: Hasher>(&self, state: &mut H) {
self.id.hash(state);
}
}
impl Borrow<Id> for Foo {
fn borrow(&self) -> &Id {
&self.id
}
}
fn main() {
let mut baz = HashSet::new();
baz.insert(Foo {
id: 1,
other_data: 2,
});
let other_data = baz.get(&1).unwrap().other_data;
println!("other_data: {}", other_data);
}
Run Code Online (Sandbox Code Playgroud)
也可以看看:
| 归档时间: |
|
| 查看次数: |
614 次 |
| 最近记录: |