【Rust自学】8.5. HashMap Pt.1:HashMap的定义、创建、合并与访问
8.5.0. 本章内容
第八章主要讲的是Rust中常见的集合。Rust中提供了很多集合类型的数据结构,这些集合可以包含很多值。但是第八章所讲的集合与数组和元组有所不同。
第八章中的集合是存储在堆内存上而非栈内存上的,这也意味着这些集合的数据大小无需在编译时就确定,在运行时它们可以动态地变大或变小。
本章主要会讲三种集合:Vector、String和HashMap(本文)
喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)
8.5.1. 什么是HashMap
HashMap的形式是HashMap<K,V>
,其中K
代表键(key),V
代表值(value)。HashMap以键值对的形式存储数据,一个键对应一个值。很多语言都支持这样的集合数据结构,但是不一定是这个叫法,比如说C#中相同概念的数据结构叫字典(dictionary)。
HashMap的内部实现使用了Hash函数,中文叫哈希函数,这个函数决定了如何在内存中存储键与值。
在Vector
中我们使用索引来访问数据,但有的时候你想要的是通过键(键可以是任何数据类型)来寻找数据,而不是通过索引(或者说你不清楚这个数据在哪个索引)。这种情况就可以使用HashMap。
需要注意的是,HashMap是同构的,也就是说在一个HashMap中,所有的键必须是同一类型,所有的值必须是同一类型。
8.5.2. 创建HashMap
- 由于HashMap不常用,所以Rust并没有把它集成到预导入模块(Prelude),使用前需要引入HashMap,在代码开头写上:
use std::collections::HashMap;
- 创建空的HashMap使用
Hash::new()
函数 - 添加数据使用
insert()
方法
看个例子:
use std::collections::HashMap; fn main() { let mut scores:HashMap<String, i32> = HashMap::new();
}
在这里创建了一个名为scores
的变量来存储HashMap,由于Rust是强语言类型,它必须知道你在HashMap里存储什么数据类型。又因为没有前后文可供编译器推断,所以在声明时就必须把HashMap里键和值的数据类型显式声明出来,在代码中就是scores
的键被设为了String
类型,值被设为了i32
类型。
当然,如果你在后文给这个HashMap上添加了数据,Rust就会根据添加的数据类型自动推断键和值的数据类型。添加数据使用insert()
方法。例子如下:
use std::collections::HashMap; fn main() { let mut scores = HashMap::new(); scores.insert(String::from("dev1ce"), 0);
}
因为在第5行往scores
里添加了键值对,且键String::from("dev1ce")
是String
类型,值0是i32
(Rust默认整数是i32
)类型,所以编译器就会自己推断出scores
是一个HashMap<String, i32>
类型的HashMap,因此第四行在声明时就不需要显式声明了。
8.5.3. 将两个Vector合为一个HashMap
在元素类型为元组的Vector
上使用collect
方法,可以使用HashMap。换个说法,假如你有两个Vector
,这两个Vector
上的所有值都有一一对应关系,这个时候就可以使用collect
方法,把一个Vector
里的数据作为键,另一个作为值,放到HashMap里。如下例:
use std::collections::HashMap; fn main() { let player = vec![String::from("dev1ce"), String::from("Zywoo")]; let initial_scores = vec![0, 100]; let scores: HashMap<_, _> = player.iter().zip(initial_scores.iter()).collect();
}
player
这个Vector
是用来存储选手名字的,里面的元素是String
类型initial_scores
这个Vector
是用来存储每个选手对应的得分的player.iter()
和initial_scores.iter()
是两个Vector
的遍历器,使用.zip()
方法就可以创建一个元组的数组,player.iter().zip(initial_scores.iter())
就是创建一个player
中的元素在前,initial_scores
中的元素在后的元组数组,想换元素位置就可以把代码中的两个迭代器呼唤位置即可。然后再使用.collect()
方法来把元组转化为HashMap。- 最后要注意的一点是
.collect()
它支持转换为很多数据结构,如果声明时不显式声明其类型程序就会报错,这里就指明了类型是HashMap<_, _>
,<>
中的两个数据类型编译器可以根据代码(也就是找两个的Vector
的数据类型)来推断,所以这里可以写_
占位符让它自行推断。
8.5.4. HashMap和所有权
对于实现了Copy trait的数据类型(例如i32
在内的绝大多数简单数据类型),值会被复制到HashMap中,原先的变量仍然可用。对于没有实现的(例如String
),所有权会被交给HashMap。
如果将值的引用插入到HashMap,值本身就不会移动。在HashMap的有效期间,被引用的值必须保持有效。
8.5.5. 访问HashMap中的值
访问值可以使用get
方法。get
方法的参数是HashMap的键,返回值是Option<&V>
这个枚举。看个例子:
use std::collections::HashMap; fn main() { let mut scores = HashMap::new(); scores.insert(String::from("dev1ce"), 0); scores.insert(String::from("Zywoo"), 100);let player_name = String::from("dev1ce"); let score = scores.get(&player_name); match score { Some(score) => println!("{}", score), None => println!("Player not found"), };
}
- 首先创建了一个空的
HashMap
叫做scores
,然后又通过insert
方法往里面添加了两个键值对(“dev1ce”, 0)和(“Zywoo”, 100),键类型是String
,值类型是i32
。 - 然后又声明了名为
player_name
的String
变量,其值为"dev1ce"。 - 接着就通过HashMap上的
get
方法在scores
找player_name
(&
表示引用)这个键所对应的值,但是get
方法返回的是Option枚举,所以这里先把这个Option枚举值赋给score
后面再来解包。 - 最后使用了
match
表达式来处理score
,如果找到了对应的值,score
这个枚举类型就会是变体Some
,把Some
所关联的值绑定在score
上,然后再打印出来。如果找不到,score
这个枚举类型就会是变体None
,这个时候就会打印"Player not found"。
输出:
0
8.5.6. 遍历HashMap
遍历HashMap一般使用for
循环。如下例:
use std::collections::HashMap; fn main() { let mut scores = HashMap::new(); scores.insert(String::from("dev1ce"), 0); scores.insert(String::from("Zywoo"), 100); for (k, v) in &scores { println!("{}: {}", k, v); }
}
这个for
循环使用的是HashMap的引用,也就是&scores
,因为通常遍历之后还要继续使用这个HashMap,所以使用引用就不会失去所有权,前面的(k,v)
是一个模式匹配,第一个值就是键,这里赋给了k
;第二个是值,这里赋给了v
。
输出:
Zywoo: 100
dev1ce: 0
相关文章:
【Rust自学】8.5. HashMap Pt.1:HashMap的定义、创建、合并与访问
8.5.0. 本章内容 第八章主要讲的是Rust中常见的集合。Rust中提供了很多集合类型的数据结构,这些集合可以包含很多值。但是第八章所讲的集合与数组和元组有所不同。 第八章中的集合是存储在堆内存上而非栈内存上的,这也意味着这些集合的数据大小无需在编…...

未来网络技术的新征程:5G、物联网与边缘计算(10/10)
一、5G 网络:引领未来通信新潮流 (一)5G 网络的特点 高速率:5G 依托良好技术架构,提供更高的网络速度,峰值要求不低于 20Gb/s,下载速度最高达 10Gbps。相比 4G 网络,5G 的基站速度…...

LLM(十二)| DeepSeek-V3 技术报告深度解读——开源模型的巅峰之作
近年来,大型语言模型(LLMs)的发展突飞猛进,逐步缩小了与通用人工智能(AGI)的差距。DeepSeek-AI 团队最新发布的 DeepSeek-V3,作为一款强大的混合专家模型(Mixture-of-Experts, MoE&a…...

Uniapp在浏览器拉起导航
Uniapp在浏览器拉起导航 最近涉及到要在浏览器中拉起导航,对目标点进行路线规划等功能,踩了一些坑,找到了使用方法。(浏览器拉起) 效果展示 可以拉起三大平台及苹果导航 点击选中某个导航,会携带经纬度跳转…...

公平联邦学习——多目标优化
前言 前段时间接触到了联邦学习(Federated Learning, FL)。涉猎了几年多目标优化的我,惊奇地发现横向联邦学习里面也有用多目标优化来做的。于是有感而发,特此写一篇博客记录记录,如有机会可以和大家多多交流。遇到不…...
奇怪的Python:为何字符串要设置成不可变的?
你好!我是老邓。今天我们来聊聊 Python 中字符串不可变这个话题。 1、问题简介: Python 中,字符串属于不可变对象。这意味着一旦字符串被创建,它的值就无法被修改。任何看似修改字符串的操作,实际上都是创建了一个新…...
Vue-Router之嵌套路由
在路由配置中,配置children import Vue from vue import VueRouter from vue-routerVue.use(VueRouter)const router new VueRouter({mode: history,base: import.meta.env.BASE_URL,routes: [{path: /,redirect: /home},{path: /home,name: home,component: () &…...
MyBatis使用的设计模式
目录 1. 工厂模式(Factory Pattern) 2. 单例模式(Singleton Pattern) 3. 代理模式(Proxy Pattern) 4. 装饰器模式(Decorator Pattern) 5. 观察者模式(Observer Patt…...
arm rk3588 升级glibc2.31到2.33
一、查看glibc版本 rootztl:~# ldd --version ldd (Ubuntu GLIBC 2.31-0ubuntu9.2) 2.31 Copyright (C) 2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNE…...

【Linux系列】sed命令的深入解析:如何使用sed删除文件内容
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
C++ 设计模式:桥接模式(Bridge Pattern)
链接:C 设计模式 链接:C 设计模式 - 装饰模式 桥接模式(Bridge Pattern)是一种结构型设计模式,它通过将抽象部分(业务功能)与实现部分(平台实现)分离,使它们…...
MATLAB中whitespacePattern函数用法
目录 语法 说明 示例 匹配空白字符 替换非标准空白 更正错误的间距 whitespacePattern函数的功能是匹配空白字符。 语法 pat whitespacePattern pat whitespacePattern(N) pat whitespacePattern(minCharacters,maxCharacters) 说明 pat whitespacePattern 创建一…...
Django多字段认证的实现
Django多字段认证 需求: django认证的检查用户是username,如果使用 username和 手机号验证登录。 重写: ModelBackend 类下的 authenticate 方法 # 在对应应用下创建 utils.py""" 修改Django认证类,为了实现 …...

【AndroidAPP】权限被拒绝:[android.permission.READ_EXTERNAL_STORAGE],USB设备访问权限系统报错
一、问题原因 1.安卓安全性变更 Android 12 的安全性变更,Google 引入了更严格的 PendingIntent 安全管理,强制要求开发者明确指定 PendingIntent 的可变性(Mutable)或不可变性(Immutable)。 但是…...
SQL进阶技巧:如何分析连续签到领金币数问题?
目录 0 题目需求 1 数据准备 2 问题分析 2.1 代码实现 2.2 代码功能分析 第一段 SQL...

1、ELK的架构和安装
ELK简介 elk:elasticsearch logstash kibana,统一日志收集系统。 elasticsearch:分布式的全文索引引擎的非关系数据库,json格式,在elk中存储所有的日志信息,架构有主和从,最少需要2台。 …...

Vue2/Vue3使用DataV
Vue2 注意vue2与3安装DataV命令命令是不同的Vue3 DataV - Vue3 官网地址 注意vue2与3安装DataV命令命令是不同的 vue3vite 与 Vue3webpack 对应安装也不同vue3vite npm install kjgl77/datav-vue3全局引入 // main.ts中全局引入 import { createApp } from vue import Da…...

汇编环境搭建
学习视频 将MASM所在目录 指定为C盘...
Android 系统 `android.app.Fragment` 类的深度定制与常见问题解析
Android 系统 android.app.Fragment 类的深度定制与常见问题解析 目录 引言Fragment 概述Fragment 的生命周期Fragment 的系统层深度定制 4.1 Fragment 的创建与初始化4.2 Fragment 的布局与视图4.3 Fragment 的通信机制4.4 Fragment 的动画与过渡4.5 Fragment 的状态保存与恢…...
linux ueditor nginx https 后台配置项返回格式出错,上传功能将不能正常使用
jsp的版本 如果出现了这个错误,上传的图标都亮起的情况,还是提示这个, 可以试试修改 uedtior.all.js 8082行 isJsonp utils.isCrossDomainUrl(configUrl); 改为 // isJsonp utils.isCrossDomainUrl(configUrl); isJsonp true; 如果还不…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

Chrome 浏览器前端与客户端双向通信实战
Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...
OCR MLLM Evaluation
为什么需要评测体系?——背景与矛盾 能干的事: 看清楚发票、身份证上的字(准确率>90%),速度飞快(眨眼间完成)。干不了的事: 碰到复杂表格(合并单元…...