当前位置: 首页 > web >正文

趣味学RUST基础篇(HashMap)

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

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

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

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

这就是 HashMap 的用武之地!

什么是哈希映射(HashMap)?

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

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

比如:

"蓝队"10"黄队"50

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

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


使用前:先开门!

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

use std::collections::HashMap;

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


创建一个“魔法储物柜”

1. 新建空柜子

let mut scores = HashMap::new();

2. 往里放东西:insert

scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);

现在柜子里有:

{"Blue": 10,"Yellow": 50
}

键(Key)和值(Value)可以是任意类型!
但所有键必须同类型,所有值也必须同类型(同质性)


怎么查东西?用 get 方法!

想查蓝队分数?

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

注意:

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

更常见的写法是:

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

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

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


遍历所有商品:for 循环

想看看柜子里都有啥?

for (team, &score) in &scores {println!("{team}: {score}");
}

输出可能是:

Yellow: 50
Blue: 10

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


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

看这段代码:

let name = String::from("Favorite color");
let value = String::from("Blue");let mut map = HashMap::new();
map.insert(name, value);println!("{}", name); // 编译错误!

为什么?因为 insert 拿走了 namevalue 的所有权

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

解决方案:插入引用

map.insert(&name, &value); // 插入引用

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


更新储物柜:三种策略

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

scores.insert("Blue", 25); // 老值 10 被干掉!

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


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

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

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

entry()HashMap神级 API
它返回一个“入口”(Entry),你可以用 or_insertor_insert_with 等方法智能操作。


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

最经典的例子:词频统计

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
}

结果:

{"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>魔法储物柜键值对,快速查找
http://www.xdnf.cn/news/19759.html

相关文章:

  • QML的focus与activeFocus
  • 【Vue2 ✨】Vue2 入门之旅(九):Vue Router 入门
  • 从“人海战术”到“AI协同”:良策金宝AI如何助力设计院数智化跃迁?
  • NLP×第六卷:她给记忆加了筛子——LSTM与GRU的贴靠机制
  • ADB图片上传轮播
  • 【MySQL】初识数据库基础
  • 12.《ACL 与 NAT 技术实验指南》
  • 基于飞算JavaAI的在线图书借阅平台设计与实现
  • 【国内外云计算平台对比:AWS/阿里云/Azure】
  • 运作管理学习笔记4-产能规划
  • 域内横向移动
  • uni-app iOS 应用版本迭代与上架实践 持续更新的高效流程
  • 教你 Centos 如何离线安装 rlwrap 插件(内网环境)
  • 【React】Redux
  • checkBox支持拖拉拽调动位置,改变布局和选择值的顺序
  • MySQL 事务的“暗面”与“高光”:故障、调优与案例复盘
  • 网络编程 socket——TCP
  • Leetcode 3665. Twisted Mirror Path Count
  • 江协科技STM32学习笔记补充之001。为什么C语言在对STM32编程过程中的二进制要用十六进制来进行读写。而不能直接用二进制来进行读写。
  • “人工智能+”时代的端侧AI:算力下沉与实时视频的新基座
  • 36. Ansible变量+管理机密
  • leetcode-python-1796字符串中第二大的数字
  • Python OpenCV图像处理与深度学习:Python OpenCV对象检测入门-Haar级联分类器与人脸检测
  • SpringCloud框架组件梳理
  • SQL Server从入门到项目实践(超值版)读书笔记 25
  • go语言面试之Goroutine 数量控制, GC回收 和任务调度
  • JimuReport 积木报表 v2.1.3 版本发布,免费开源的可视化报表和大屏
  • 2025 金融行业证书怎么选?从能力适配到职业方向的理性梳理
  • 别让你的 AI 对话烂在聊天记录里!
  • 马健涛事件折射出中国音乐产业转型期的深层矛盾,最终解决之道在于完善我国音乐版权鉴定的技术标准