任何实现了 Eq 和 Hash 特征的类型都可以用于 HashMap 的 key,包括:
bool (虽然很少用到,因为它只能表达两种 key)
int , uint 以及它们的变体,例如 u8 、 i32 等
String 和 &str (提示: HashMap 的 key 是 String 类型时,你其实可以使用 &str 配合 get 方
法进行查询
需要注意的是, f32 和 f64 并没有实现 Hash ,原因是 浮点数精度 的问题会导致它们无法进行相等比
较。
如果一个集合类型的所有字段都实现了 Eq 和 Hash ,那该集合类型会自动实现 Eq 和 Hash 。例如
Vect<T> 要实现 Hash ,那么首先需要 T 实现 Hash 。
4. 🌟🌟
// 修 复 错 误
// 提 示: `derive` 是 实 现 一 些 常 用 特 征 的 好 办 法
use std::collections::HashMap;
struct Viking {
name: String,
country: String,
}
impl Viking {
fn new(name: &str, country: &str) -> Viking {
Viking {
name: name.to_string(),
country: country.to_string(),
}
}
}
fn main() {
// 使 用 HashMap 来 存 储 viking 的 生 命 值
let vikings = HashMap::from([
(Viking::new("Einar", "Norway"), 25),
(Viking::new("Olaf", "Denmark"), 24),
(Viking::new("Harald", "Iceland"), 12),
]);
// 使 用 derive 的 方 式 来 打 印 viking 的 当 前 状 态
for (viking, health) in &vikings {
println!("{:?} has {} hp", viking, health);
}
}
容量
关于容量,我们在之前的 Vector 中有详细的介绍,而 HashMap 也可以调整容量: 你可以通过
HashMap::with_capacity(uint) 使用指定的容量来初始化,或者使用 HashMap::new() ,后者会提供
一个默认的初始化容量。
示例
use std::collections::HashMap;
fn main() {
let mut map: HashMap<i32, i32> = HashMap::with_capacity(100);
map.insert(1, 2);
map.insert(3, 4);
// 事 实 上 , 虽 然 我 们 使 用 了 100 容 量 来 初 始 化 , 但 是 map 的 容 量 很 可 能 会 比 100 更 多
assert!(map.capacity() >= 100);
// 对 容 量 进 行 收 缩 , 你 提 供 的 值 仅 仅 是 一 个 允 许 的 最 小 值 , 实 际 上 ,Rust 会 根 据 当 前 存 储 的 数 据
map.shrink_to(50);
assert!(map.capacity() >= 50);
// 让 Rust 自 行 调 整 到 一 个 合 适 的 值 , 剩 余 策 略 同 上
map.shrink_to_fit();
assert!(map.capacity() >= 2);
println!("Success!")
}