【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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/64702.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/64702.shtml
英文地址,請注明出處:http://en.pswp.cn/web/64702.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

混合合并兩個pdf文件

混合兩個pdf 1、在線免費交替和混合奇數和偶數PDF頁面2、有什么軟件把兩個 PDF 交叉合并&#xff1f;3、pdfsam本地合并 如何Google翻譯的原文和譯文合并&#xff0c;&#xff08;沉浸式翻譯效果相對較好&#xff09; 1、在線免費交替和混合奇數和偶數PDF頁面 https://deftpd…

Hutool 發送 HTTP 請求的幾種常見寫法

最簡單的 GET 請求&#xff1a; String result HttpUtil.get("https://www.baidu.com");帶參數的 GET 請求&#xff1a; // 方法1: 直接拼接URL參數 String result HttpUtil.get("https://www.baidu.com?name張三&age18");// 方法2: 使用 HashMap…

獲取用戶詳細信息-ThreadLocal優化

Thread全局接口可用&#xff0c;不用再重復編寫。所以為了代碼的復用&#xff0c;使用Thread。把之前的內容&#xff08;函數的參數和map與username&#xff09;注釋掉&#xff0c;換為Thread傳過來的內容&#xff08;map與username&#xff09;。 因為Thread需要在攔截器里面…

THUCNews解壓/THUCNews數據集解壓出問題

省流&#xff1a;使用zip64進行解壓&#xff0c;文件數目太多windows默認zip16裝不下 我在使用THUCNews中文文本數據集時出現了問題&#xff0c;原數據集解壓后應該包含以下兩個文件夾: 其中THUCNews文件夾下有以新聞類別命名的子文件。官網下載的是一個1.56GB的zip壓縮包 而我…

MySQL使用通用二進制文件安裝到Unix/Linux

Oracle提供了一組MySQL的二進制發行版。其中包括用于許多平臺的壓縮tar文件&#xff08;擴展名為.tar.xz的文件&#xff09;形式的通用二進制發行版&#xff0c;以及用于選定平臺的特定平臺包格式的二進制文件。 本節介紹在Unix/Linux平臺上從壓縮的tar文件二進制分布安裝MySQ…

安卓/system/bin下命令中文說明(AI)

ATFWD-daemon&#xff1a;AT指令轉發守護進程&#xff0c;用于將AT指令從應用層轉發到調制解調器。 PktRspTest&#xff1a;數據包響應測試工具。 StoreKeybox&#xff1a;存儲密鑰盒工具&#xff0c;用于安全地存儲加密密鑰。 WifiLogger_app&#xff1a;WiFi日志記錄應用&…

Git操作總結

可以直接看實踐 總結自施磊老師課程 Git與SVN對比 svn操作流程 寫代碼。 從服務器拉回服務器的當前版本庫&#xff0c;并解決服務器版本庫與本地代碼的沖突。 將本地代碼提交到服務器。 Git操作流程 寫代碼&#xff0c; 然后添加&#xff08;add&#xff09;到暫存區。 …

直流開關電源技術及應用二

文章目錄 8 PFC8.1 基本概念8.1.1 功率因數8.1.2 功率因數偏低帶來的影響8.1.3 特點 8.2 有源功率因數校正原理8.2.1不連續工作模式的矯正原理恒頻控制技術控制目標控制關鍵要素控制過程實現方式公式Boost電路和boost pfc電路的聯系和區別聯系區別 恒導通時間控制 8.2.2 連續工…

UNI-APP_i18n國際化引入

官方文檔&#xff1a;https://uniapp.dcloud.net.cn/tutorial/i18n.html vue2中使用 1. 新建文件 locale/index.js import en from ./en.json import zhHans from ./zh-Hans.json import zhHant from ./zh-Hant.json const messages {en,zh-Hans: zhHans,zh-Hant: zhHant }…

typora+picgo core+minio自動上傳圖片

1. 在服務器上安裝docker版本minio 創建/docker/minio文件夾 mkdir -p /docker/minio在此文件夾創建docker-compose.yml version: "3.5" services:minio:image: quay.io/minio/minio:latestcontainer_name: minioprivileged: truerestart: alwaysports:# API接口訪…

論文筆記:DepthLab: From Partial to Complete

是一篇很精煉的論文&#xff0c;不知道咋總結了&#xff0c;就差全文翻譯了&#xff0c;不過在這里我主要關注3D部分&#xff0c;因為他的pipeline是基于SD的&#xff0c;框圖也比較清晰易懂&#xff0c;非常細節的內容可以回頭看論文&#xff0c;哈哈哈&#xff0c;給作者大佬…

LeetCode--排序算法(堆排序、歸并排序、快速排序)

排序算法 歸并排序算法思路代碼時間復雜度 堆排序什么是堆&#xff1f;如何維護堆&#xff1f;如何建堆&#xff1f;堆排序時間復雜度 快速排序算法思想代碼時間復雜度 歸并排序 算法思路 歸并排序算法有兩個基本的操作&#xff0c;一個是分&#xff0c;也就是把原數組劃分成…

ShardingSphere-Proxy分表場景:go測試案例

接續上篇文章《ShardingSphere-Proxy分表場景測試案例》 go測試用例&#xff1a; package mainimport ("fmt""math/rand""time""github.com/bwmarrin/snowflake""gorm.io/driver/mysql""gorm.io/gorm""gor…

主流在售AI電子寵物產品

市面上已經有許多類型的AI電子寵物產品&#xff0c;它們各具特色&#xff0c;旨在提供情感陪伴、教育娛樂以及智能互動等功能。以下是幾款在市場上較為知名的AI電子寵物玩具&#xff0c;涵蓋了不同的形態和技術特點&#xff1a; 1. Moflin 制造商&#xff1a;日本消費電子公司…

Debian-linux運維-docker安裝和配置

騰訊云搭建docker官方文檔&#xff1a;https://cloud.tencent.com/document/product/213/46000 阿里云安裝Docker官方文檔&#xff1a;https://help.aliyun.com/zh/ecs/use-cases/install-and-use-docker-on-a-linux-ecs-instance 天翼云常見docker源配置指導&#xff1a;htt…

【機器學習 | 數據挖掘】時間序列算法

時間序列是按時間順序排列的、隨時間變化且相互關聯的數據序列。分析時間序列的方法構成數據分析的一個重要領域&#xff0c;即時間序列分析。以下是對時間序列算法的詳細介紹&#xff1a; 一、時間序列的分類 時間序列根據所研究的依據不同&#xff0c;可有不同的分類&#…

Qt6.8.1 Mingw13.1 編譯opencv4.10時cannot convert ‘char*‘ to ‘LPWSTR

當選擇build_world時出錯 G:\ForOpencv4.10\opencv-4.10.0\modules\core\src\utils\filesystem.cpp: In function cv::String cv::utils::fs::getCacheDirectory(const char*, const char*): G:\ForOpencv4.10\opencv-4.10.0\modules\core\src\utils\filesystem.cpp:442:43: e…

MIT S081 Lab 2 System Calls

Lab鏈接 一 實現trace功能 1 題目要求 In this assignment you will add a system call tracing feature that may help you when debugging later labs. You’ll create a new trace system call that will control tracing. It should take one argument, an integer “ma…

[Linux] 服務器CPU信息

&#xff08;1&#xff09;查看CPU信息&#xff08;型號&#xff09; cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c輸出&#xff1a;可以看到有128個虛擬CPU核心&#xff0c;型號是后面一串 128 Intel(R) Xeon(R) Platinum 8336C CPU 2.30GHz&#xff08;2&…

通過無障礙服務(AccessibilityService)實現Android設備全局水印顯示

一、無障礙功能簡介 首先我們先來了解下無障礙功能的官方介紹&#xff1a; 無障礙服務僅應用于幫助殘障用戶使用 Android 設備和應用。它們在后臺運行&#xff0c;并在觸發 AccessibilityEvents 時接收系統的回調。此類事件表示用戶界面中的某些狀態轉換&#xff0c;例如焦點已…