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

趣味学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.dtcms.com/a/362754.html

相关文章:

  • 二叉树的非递归遍历 | 秋招面试必备
  • Spring Bean
  • LLM面试50问:NLP/RAG/部署/对齐/安全/多模态全覆盖
  • R语言根据经纬度获得对应样本的省份
  • WPF依赖属性和依赖属性的包装器:
  • iOS混淆工具实战 视频流媒体类 App 的版权与播放安全保护
  • 安卓学习 之 gradle下载失败的解决方法
  • Elasticsearch面试精讲 Day 5:倒排索引原理与实现
  • 跨越产业技术障碍、创新制造模式的智慧工业开源了
  • 【开题答辩全过程】以宠物生活社区为例,包含答辩的问题和答案
  • 扩散模型驱动的智能设计与制造:下一场工业革命?
  • 最新!阿里财报电话会蒋凡与吴泳铭透露重要信息:淘宝闪购成绩斐然;零售与AI双轮驱动;阿里云推出“Agent Bay”新产品···
  • 物联网为何离不开天硕工业级SSD固态硬盘?
  • maven 常用指令
  • Corona渲染噪点终结指南:3ds Max高效去噪全攻略
  • 【3D 入门-3】常见 3D 格式对比,.glb / .obj / .stl / .ply
  • 通信中FDD和TDD的区别
  • 【SpringBootWeb开发】《一篇带你入门Web后端开发》
  • 242. 有效的字母异位词| 349. 两个数组的交集
  • 框架-SpringMVC-1
  • 手写Muduo网络库核心代码1-- noncopyable、Timestamp、InetAddress、Channel 最详细讲解
  • hive udf 执行一次调用多次问题
  • 算法 --- 模拟
  • HDFS读写机制深度解析:分布式存储的核心奥秘
  • Zookeeper分布式锁原理
  • java-设计模式-5-创建型模式-建造
  • 科普:为什么在开发板上运行 Qt 程序时需要在命令后加 -platform linuxfb
  • 少儿舞蹈小程序从0到1(5):搭建关于我们页面
  • 深入浅出 RabbitMQ - SpringBoot2.X整合RabbitMQ实战
  • 23种设计模式-抽象工厂模式