趣味学RUST基础篇(HashMap)

HashMap<K, V>:Rust 里的"魔法储物柜"!

学些HashMap,我们还是举个栗子说明:假设你开了一家超市:

  • 顾客不会说:"我要第三排第二个货架上的东西。"
  • 他们会说:"我要一包蓝龙牌辣条 !" 或者 "来一瓶黄泉牌汽水!"

你总不能靠数货架来找商品吧?你需要一个智能货架系统------

这就是 HashMap 的用武之地!

什么是哈希映射(HashMap)?

HashMap<K, V> 就像一个魔法储物柜:

  • 每个抽屉都有一个标签(Key)
  • 抽屉里放着对应的物品(Value)

比如:

rust 复制代码
"蓝队" → 10 分  
"黄队" → 50 分

你想查蓝队得分?直接问:"蓝队多少分? " → 系统秒回:10!

它不靠"第几个",而是靠"叫什么"来查找,又快又准!


使用前:先开门!

HashMap 不在 Rust 的"默认工具包"里,得先开门:

rust 复制代码
use std::collections::HashMap;

就像你要用特殊保险柜,得先申请权限。


创建一个"魔法储物柜"

1. 新建空柜子

rust 复制代码
let mut scores = HashMap::new();

2. 往里放东西:insert

rust 复制代码
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);

现在柜子里有:

复制代码
{
  "Blue": 10,
  "Yellow": 50
}

键(Key)和值(Value)可以是任意类型!

但所有键必须同类型,所有值也必须同类型(同质性)


怎么查东西?用 get 方法!

想查蓝队分数?

rust 复制代码
let team = String::from("Blue");
let score = scores.get(&team);  // 返回 Option<&i32>

注意:

  • get 返回的是 Option<&V>,因为可能没有这个键!
  • 所以你得处理 Some 和 None。

更常见的写法是:

rust 复制代码
let score = scores.get(&team).copied().unwrap_or(0);
// 如果没有,就默认为 0

.copied():把 &i32 变成 i32(因为 i32 可以复制)

.unwrap_or(0):没有就返回 0


遍历所有商品:for 循环

想看看柜子里都有啥?

rust 复制代码
for (team, &score) in &scores {
    println!("{team}: {score}");
}

输出可能是:

text 复制代码
Yellow: 50
Blue: 10

顺序是随机的 !HashMap 不保证顺序(它是哈希的,不是列表)。


所有权规则:放进去了,就归我了!

看这段代码:

rust 复制代码
let name = String::from("Favorite color");
let value = String::from("Blue");

let mut map = HashMap::new();
map.insert(name, value);

println!("{}", name); // 编译错误!

为什么?因为 insert 拿走了 name 和 value 的所有权!

就像你把身份证交给银行办业务,办完前你不能再用它。

解决方案:插入引用

rust 复制代码
map.insert(&name, &value); // 插入引用

但注意:这些引用必须活得比 HashMap 久,否则会变成"悬空指针"!


更新储物柜:三种策略

策略一:直接覆盖(暴力更新)

rust 复制代码
scores.insert("Blue", 25); // 老值 10 被干掉!

简单粗暴,适合"最新值最重要"的场景。


策略二:只在没有时才插入(谨慎更新)

你想加个新队,但不想覆盖旧数据:

rust 复制代码
scores.entry("Red").or_insert(30);
  • 如果 "Red" 没有,就插入 30
  • 如果已有,就不动它

entry() 是 HashMap 的神级 API !

它返回一个"入口"(Entry),你可以用 or_insert、or_insert_with 等方法智能操作。


策略三:基于旧值更新(智能叠加)

最经典的例子:词频统计!

rust 复制代码
let text = "hello world hello rust world";

let mut word_count = HashMap::new();

for word in text.split_whitespace() {
    let count = word_count.entry(word).or_insert(0);
    *count += 1;  // 解引用后 +1
}

结果:

rust 复制代码
{
  "hello": 2,
  "world": 2,
  "rust": 1
}

关键点:

  • or_insert(0) 返回 &mut i32(可变引用)
  • 用 *count += 1 修改它
  • 引用在循环结束时自动释放,安全!

哈希函数:柜子背后的"分拣机器人"

HashMap 为什么这么快?因为它用哈希函数把钥匙(Key)变成"抽屉编号"。

Rust 默认用 SipHash:

  • 安全:防黑客攻击(防止"哈希碰撞攻击")
  • 稍慢:不是最快的算法

如果你发现性能瓶颈,可以换更快的 hasher(比如 ahash),但一般没必要。

想换?去 crates.io 找找看!

小结:HashMap 使用口诀

操作 方法
创建 HashMap::new()
插入 insert(key, value)
查询 get(&key) → 返回 Option<&V>
遍历 for (k, v) in &map
智能插入 entry(key).or_insert(value)
词频统计 *entry(key).or_insert(0) += 1
所有权 值会被 move,引用需注意生命周期

三神器合体:Rust 冒险者工具箱

容器 别名 适用场景
Vec<T> 魔法背包 有序列表,按索引访问
String 魔法卷轴 存文本,支持 UTF-8
HashMap<K,V> 魔法储物柜 键值对,快速查找
相关推荐
朝朝辞暮i2 小时前
C++ 第 23 课:class —— 开始真正进入面向对象
开发语言·c++·算法
明月_清风3 小时前
Muse 登顶 App Store 第一,SDK 直接开源:AI Agent 开始进入下一个阶段
人工智能·后端
leikooo3 小时前
用餐厅和盘子理解栈和堆
java·数据结构·链表·rust
小师兄吃牛肉3 小时前
C语言篇:宏
c语言·开发语言
郑同学的笔记3 小时前
【c++随笔28】strcmp 和 memcmp对比
开发语言·c++
言乐64 小时前
Python根据无法识别搜索词找出可能输入内容模型
开发语言·python·django·virtualenv·pygame
weixin_307779134 小时前
有限产能智能排产与动态重排智能体:从需求解构到技术实现
开发语言·人工智能·算法·架构
kakakahahahaha4 小时前
Windows C盘临时文件清理:%temp%、Windows Temp、Prefetch、Windows.old与hiberfil.sys处理指南
c语言·开发语言·windows
朝朝辞暮i4 小时前
C++ 第 27 课:智能指针 shared_ptr
开发语言·c++·算法
朝朝辞暮i5 小时前
C++ 第 29 课:回调函数 Callback
开发语言·c++·算法