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

【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_nameString变量,其值为"dev1ce"。
  • 接着就通过HashMap上的get方法在scoresplayer_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中提供了很多集合类型的数据结构&#xff0c;这些集合可以包含很多值。但是第八章所讲的集合与数组和元组有所不同。 第八章中的集合是存储在堆内存上而非栈内存上的&#xff0c;这也意味着这些集合的数据大小无需在编…...

未来网络技术的新征程:5G、物联网与边缘计算(10/10)

一、5G 网络&#xff1a;引领未来通信新潮流 &#xff08;一&#xff09;5G 网络的特点 高速率&#xff1a;5G 依托良好技术架构&#xff0c;提供更高的网络速度&#xff0c;峰值要求不低于 20Gb/s&#xff0c;下载速度最高达 10Gbps。相比 4G 网络&#xff0c;5G 的基站速度…...

LLM(十二)| DeepSeek-V3 技术报告深度解读——开源模型的巅峰之作

近年来&#xff0c;大型语言模型&#xff08;LLMs&#xff09;的发展突飞猛进&#xff0c;逐步缩小了与通用人工智能&#xff08;AGI&#xff09;的差距。DeepSeek-AI 团队最新发布的 DeepSeek-V3&#xff0c;作为一款强大的混合专家模型&#xff08;Mixture-of-Experts, MoE&a…...

Uniapp在浏览器拉起导航

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

公平联邦学习——多目标优化

前言 前段时间接触到了联邦学习&#xff08;Federated Learning, FL&#xff09;。涉猎了几年多目标优化的我&#xff0c;惊奇地发现横向联邦学习里面也有用多目标优化来做的。于是有感而发&#xff0c;特此写一篇博客记录记录&#xff0c;如有机会可以和大家多多交流。遇到不…...

奇怪的Python:为何字符串要设置成不可变的?

你好&#xff01;我是老邓。今天我们来聊聊 Python 中字符串不可变这个话题。 1、问题简介&#xff1a; Python 中&#xff0c;字符串属于不可变对象。这意味着一旦字符串被创建&#xff0c;它的值就无法被修改。任何看似修改字符串的操作&#xff0c;实际上都是创建了一个新…...

Vue-Router之嵌套路由

在路由配置中&#xff0c;配置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. 工厂模式&#xff08;Factory Pattern&#xff09; 2. 单例模式&#xff08;Singleton Pattern&#xff09; 3. 代理模式&#xff08;Proxy Pattern&#xff09; 4. 装饰器模式&#xff08;Decorator Pattern&#xff09; 5. 观察者模式&#xff08;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删除文件内容

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

C++ 设计模式:桥接模式(Bridge Pattern)

链接&#xff1a;C 设计模式 链接&#xff1a;C 设计模式 - 装饰模式 桥接模式&#xff08;Bridge Pattern&#xff09;是一种结构型设计模式&#xff0c;它通过将抽象部分&#xff08;业务功能&#xff09;与实现部分&#xff08;平台实现&#xff09;分离&#xff0c;使它们…...

MATLAB中whitespacePattern函数用法

目录 语法 说明 示例 匹配空白字符 替换非标准空白 更正错误的间距 whitespacePattern函数的功能是匹配空白字符。 语法 pat whitespacePattern pat whitespacePattern(N) pat whitespacePattern(minCharacters,maxCharacters) 说明 pat whitespacePattern 创建一…...

Django多字段认证的实现

Django多字段认证 需求&#xff1a; django认证的检查用户是username&#xff0c;如果使用 username和 手机号验证登录。 重写&#xff1a; ModelBackend 类下的 authenticate 方法 # 在对应应用下创建 utils.py""" 修改Django认证类&#xff0c;为了实现 …...

【AndroidAPP】权限被拒绝:[android.permission.READ_EXTERNAL_STORAGE],USB设备访问权限系统报错

一、问题原因 1.安卓安全性变更 Android 12 的安全性变更&#xff0c;Google 引入了更严格的 PendingIntent 安全管理&#xff0c;强制要求开发者明确指定 PendingIntent 的可变性&#xff08;Mutable&#xff09;或不可变性&#xff08;Immutable&#xff09;。 但是&#xf…...

SQL进阶技巧:如何分析连续签到领金币数问题?

目录 0 题目需求 1 数据准备 2 问题分析 2.1 代码实现 2.2 代码功能分析 第一段 SQL...

1、ELK的架构和安装

ELK简介 elk&#xff1a;elasticsearch logstash kibana&#xff0c;统一日志收集系统。 elasticsearch&#xff1a;分布式的全文索引引擎的非关系数据库&#xff0c;json格式&#xff0c;在elk中存储所有的日志信息&#xff0c;架构有主和从&#xff0c;最少需要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的版本 如果出现了这个错误&#xff0c;上传的图标都亮起的情况&#xff0c;还是提示这个&#xff0c; 可以试试修改 uedtior.all.js 8082行 isJsonp utils.isCrossDomainUrl(configUrl); 改为 // isJsonp utils.isCrossDomainUrl(configUrl); isJsonp true; 如果还不…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...

Python训练营-Day26-函数专题1:函数定义与参数

题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一个名为 calculate_circle_area 的函数&#xff0c;该函数接收圆的半径 radius 作为参数&#xff0c;并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求&#xff1a;函数接收一个位置参数 radi…...

在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例

目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码&#xff1a;冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...