欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Rust中HashMap類(lèi)型的使用詳解

 更新時(shí)間:2024年03月14日 09:32:10   作者:希望_睿智  
Rust中一種常見(jiàn)的集合類(lèi)型是哈希映射,本文主要介紹了Rust中HashMap類(lèi)型的使用詳解,包含創(chuàng)建訪(fǎng)問(wèn)修改遍歷等,具有一定的參考價(jià)值,感興趣的可以了解一下

概述

HashMap,被稱(chēng)為哈希表或散列表,是一種可以存儲(chǔ)鍵值對(duì)的數(shù)據(jù)結(jié)構(gòu)。它使用哈希函數(shù)將鍵映射到存儲(chǔ)位置,以便可以快速檢索和更新元素。這種數(shù)據(jù)結(jié)構(gòu)在許多編程語(yǔ)言中都存在,而在Rust中,它被實(shí)現(xiàn)為HashMap<K, V>。其中,K表示鍵的類(lèi)型,V表示值的類(lèi)型。HashMap以哈希表為基礎(chǔ)實(shí)現(xiàn),允許我們?cè)诔?shù)平均時(shí)間復(fù)雜度內(nèi)完成插入、刪除和查找操作。

HashMap的創(chuàng)建

Rust標(biāo)準(zhǔn)庫(kù)中提供了std::collections::HashMap<K, V>,這是一個(gè)關(guān)聯(lián)數(shù)組或映射。其中,K是鍵類(lèi)型,必須實(shí)現(xiàn)Eq和Hash traits以確保鍵的唯一性和能夠進(jìn)行哈希計(jì)算。V是值類(lèi)型,可以是任何Rust支持的類(lèi)型。

每個(gè)鍵都會(huì)通過(guò)哈希函數(shù)轉(zhuǎn)化為一個(gè)索引,并以此存儲(chǔ)對(duì)應(yīng)的值,從而使得通過(guò)鍵快速定位到值成為可能。當(dāng)兩個(gè)不同的鍵通過(guò)哈希函數(shù)得到相同的索引時(shí),會(huì)發(fā)生“哈希沖突”。此時(shí),HashMap會(huì)通過(guò)開(kāi)放尋址法或者鏈地址法等策略來(lái)解決這個(gè)問(wèn)題。

要使用HashMap,必須先引入std::collections::HashMap模塊。新建HashMap,主要有以下幾種方式。

1、使用new函數(shù)創(chuàng)建一個(gè)新的、空的HashMap。

use std::collections::HashMap;

fn main() {
    // 創(chuàng)建一個(gè)空的HashMap,鍵類(lèi)型為String,值類(lèi)型為i32
    let mut map_fruit: HashMap<String, i32> = HashMap::new();
    
    // 插入一些鍵值對(duì)
    map_fruit.insert("Lemon".to_string(), 66);
    map_fruit.insert("Apple".to_string(), 99);
    // 輸出:{"Lemon": 66, "Apple": 99}
    println!("{:?}", map_fruit);
}

2、新建帶有元素的HashMap。通過(guò)傳入一個(gè)鍵值對(duì)的集合(比如:數(shù)組、切片或迭代器),我們可以在創(chuàng)建HashMap的同時(shí)初始化它。這可以通過(guò)collect方法來(lái)實(shí)現(xiàn),它通常與vec!宏或數(shù)組字面量一起使用,以創(chuàng)建包含(key, value)元組的集合。在下面的示例代碼中,我們首先創(chuàng)建了一個(gè)HashMap。它的鍵是String類(lèi)型,值是i32類(lèi)型。然后,我們使用vec!宏創(chuàng)建了一個(gè)包含三個(gè)(key, value)元組的向量,并使用into_iter方法將其轉(zhuǎn)換為迭代器。最后,我們使用collect方法將其收集到一個(gè)HashMap中。

use std::collections::HashMap;

fn main() {
    let map_fruit: HashMap<String, i32> = vec![
        ("Lemon".to_string(), 66), 
        ("Apple".to_string(), 99)].into_iter().collect();
    
    // 輸出:{"Lemon": 66, "Apple": 99}
    println!("{:?}", map_fruit);
}

3、HashMap::from是一個(gè)創(chuàng)建HashMap的便捷方法,主要用于從實(shí)現(xiàn)了IntoIterator特征且迭代器產(chǎn)出元組 (K, V) 的類(lèi)型創(chuàng)建一個(gè)HashMap。

use std::collections::HashMap;

fn main() {
    let pairs = [("Lemon".to_string(), 66), ("Apple".to_string(), 99)];
    let map_fruit = HashMap::from(pairs);

    // 輸出:{"Lemon": 66, "Apple": 99}
    println!("{:?}", map_fruit);
}

4、使用with_capacity函數(shù)創(chuàng)建預(yù)先分配指定容量的HashMap。注意:預(yù)設(shè)容量只是預(yù)留空間,實(shí)際使用的數(shù)量會(huì)根據(jù)插入的鍵值對(duì)自動(dòng)增長(zhǎng)。

use std::collections::HashMap;

fn main() {
    // 創(chuàng)建一個(gè)初始容量為5的HashMap
    let mut map_fruit: HashMap<String, i32> = HashMap::with_capacity(5);
    
    // 插入一些鍵值對(duì)
    map_fruit.insert("Lemon".to_string(), 66);
    map_fruit.insert("Apple".to_string(), 99);
    // 輸出:{"Lemon": 66, "Apple": 99}
    println!("{:?}", map_fruit);
}

HashMap的訪(fǎng)問(wèn)

HashMap是一個(gè)存儲(chǔ)鍵值對(duì)的數(shù)據(jù)結(jié)構(gòu),并且可以通過(guò)鍵來(lái)快速檢索值。為了訪(fǎng)問(wèn)HashMap中的值,我們可以使用get方法或get_mut方法,具體取決于是否需要獲取值的可變引用。

1、get方法用于獲取與給定鍵相關(guān)聯(lián)的值的不可變引用。如果鍵存在于HashMap中,get將返回Some(value),其中value是與該鍵相關(guān)聯(lián)的值的引用。如果鍵不存在,它將返回None。

use std::collections::HashMap;

fn main() {
    let mut map_fruit = HashMap::new();
    map_fruit.insert("Lemon".to_string(), 66);
    map_fruit.insert("Apple".to_string(), 99);

    // 訪(fǎng)問(wèn)存在的鍵
    if let Some(value) = map_fruit.get("Apple") {
        println!("found value: {}", value);
    } else {
        println!("not found");
    }
  
    // 訪(fǎng)問(wèn)不存在的鍵
    if let Some(value) = map_fruit.get("Peach") {
        println!("found value: {}", value);
    } else {
        println!("not found");
    }
}

2、如果我們需要獲取值的可變引用以便修改它,則應(yīng)該使用get_mut方法。與get方法類(lèi)似,如果鍵存在于HashMap中,get_mut將返回Some(&mut value),其中&mut value是與該鍵相關(guān)聯(lián)的值的可變引用。如果鍵不存在,它將返回None。

use std::collections::HashMap;

fn main() {
    let mut map_fruit = HashMap::new();
    map_fruit.insert("Lemon".to_string(), 66);
    map_fruit.insert("Apple".to_string(), 99);

    // 訪(fǎng)問(wèn)存在的鍵
    if let Some(value) = map_fruit.get_mut("Apple") {
        *value = 100;
    } else {
        println!("not found");
    }

    // 輸出:{"Apple": 100, "Lemon": 66}
    println!("{:?}", map_fruit);
  
    // 訪(fǎng)問(wèn)不存在的鍵
    if let Some(value) = map_fruit.get_mut("Peach") {
        println!("found value: {}", value);
    } else {
        println!("not found");
    }
}

HashMap的修改

1、插入新鍵值對(duì)。如果鍵不存在,使用insert方法將添加一個(gè)新的鍵值對(duì)。如果鍵已經(jīng)存在,則會(huì)替換原有的值。

use std::collections::HashMap;

fn main() {
    // 創(chuàng)建一個(gè)空的HashMap,鍵類(lèi)型為String,值類(lèi)型為i32
    let mut map_fruit: HashMap<String, i32> = HashMap::new();
    
    // 插入一些鍵值對(duì)
    map_fruit.insert("Lemon".to_string(), 66);
    map_fruit.insert("Apple".to_string(), 99);
    // 輸出:{"Lemon": 66, "Apple": 99}
    println!("{:?}", map_fruit);
}

2、如果需要根據(jù)鍵是否存在來(lái)執(zhí)行不同的操作(比如:只在鍵不存在時(shí)插入值,或者在鍵存在時(shí)更新值),可以使用entry API。這提供了更細(xì)粒度的控制,并避免了不必要的查找。entry方法會(huì)根據(jù)鍵是否存在返回一個(gè)Entry枚舉;or_insert方法會(huì)在鍵不存在時(shí)插入給定的值,并返回鍵的值的可變引用;and_modify方法會(huì)修改現(xiàn)有的值。

use std::collections::HashMap;

fn main() {
    let mut map_fruit = HashMap::new();
    map_fruit.insert("Lemon".to_string(), 66);
    map_fruit.insert("Apple".to_string(), 99);

    // 使用entry API插入新的鍵值對(duì),并修改值為原來(lái)的2倍
    map_fruit.entry("Peach".to_string()).or_insert(256);
    map_fruit.entry("Peach".to_string()).and_modify(|v| *v *= 2);
    // 輸出: {"Peach": 512, "Lemon": 66, "Apple": 99}
    println!("{:?}", map_fruit);
}

3、使用remove方法可以移除指定鍵的鍵值對(duì)。當(dāng)我們調(diào)用remove方法并傳入一個(gè)鍵時(shí),如果該鍵存在于HashMap中,它會(huì)返回與該鍵相關(guān)聯(lián)的值,并從HashMap中刪除該鍵值對(duì)。如果鍵不存在,會(huì)返回None。

use std::collections::HashMap;

fn main() {
    let mut map_fruit = HashMap::new();
    map_fruit.insert("Lemon".to_string(), 66);
    map_fruit.insert("Apple".to_string(), 99);

    // 嘗試刪除并獲取"Lemon"的值,會(huì)成功
    if let Some(value) = map_fruit.remove("Lemon") {
        println!("{} removed", value);
    } else {
        println!("not found");
    }

    // 嘗試刪除并獲取"Peach"的值,會(huì)失敗
    if let Some(value) = map_fruit.remove("Peach") {
        println!("{} removed", value);
    } else {
        println!("not found");
    }

    // 輸出: {"Apple": 99}
    println!("{:?}", map_fruit);
}

HashMap的遍歷

在Rust中,我們可以使用多種方式來(lái)遍歷HashMap,包括:遍歷所有的鍵、遍歷所有的值、同時(shí)遍歷鍵和值。

1、遍歷所有的鍵。我們可以使用keys()方法來(lái)獲取一個(gè)包含所有鍵的迭代器,并遍歷它們。

use std::collections::HashMap;

fn main() {
    let pairs = [("Lemon".to_string(), 66), ("Apple".to_string(), 99)];
    let map_fruit = HashMap::from(pairs);

    // 分別輸出:Lemon Apple
    for key in map_fruit.keys() {
        println!("{}", key);
    }
}

2、遍歷所有的值。我們可以使用values()方法來(lái)獲取一個(gè)包含所有值的迭代器,并遍歷它們。

use std::collections::HashMap;

fn main() {
    let pairs = [("Lemon".to_string(), 66), ("Apple".to_string(), 99)];
    let map_fruit = HashMap::from(pairs);

    // 分別輸出:99 66
    for value in map_fruit.values() {
        println!("{}", value);
    }
}

3、同時(shí)遍歷鍵和值。如果需要同時(shí)訪(fǎng)問(wèn)鍵和值,我們可以使用iter()方法,它會(huì)返回一個(gè)包含鍵值對(duì)引用的迭代器。

use std::collections::HashMap;

fn main() {
    let pairs = [("Lemon".to_string(), 66), ("Apple".to_string(), 99)];
    let map_fruit = HashMap::from(pairs);

    // 分別輸出:Apple: 99 Lemon: 66
    for (key, value) in map_fruit.iter() {
        println!("{}: {}", key, value);
    }
}

4、遍歷并修改值。如果需要遍歷HashMap并修改其中的值,我們可以使用iter_mut()方法,它會(huì)返回一個(gè)包含可變鍵值對(duì)引用的迭代器。注意:當(dāng)使用iter_mut()方法時(shí),不能有其他對(duì)HashMap或其任何元素的可變引用。因?yàn)镽ust的借用規(guī)則要求:在同一時(shí)間,變量只能有一個(gè)可變引用存在。

use std::collections::HashMap;

fn main() {
    let pairs = [("Lemon".to_string(), 66), ("Apple".to_string(), 99)];
    let mut map_fruit = HashMap::from(pairs);

    // 修改值為原來(lái)的10倍
    for (key, value) in map_fruit.iter_mut() {
        *value *= 10; 
    }

    // 分別輸出:Lemon: 660 Apple: 990
    for (key, value) in map_fruit.iter() {
        println!("{}: {}", key, value);
    }
}

HashMap的所有權(quán)

在Rust中,HashMap對(duì)插入其中的鍵值對(duì)的所有權(quán)規(guī)則,遵循Rust語(yǔ)言的核心所有權(quán)原則。這意味著,當(dāng)我們將一個(gè)值放入HashMap時(shí),會(huì)根據(jù)值的類(lèi)型決定所有權(quán)如何轉(zhuǎn)移。

1、復(fù)制所有權(quán)。對(duì)于實(shí)現(xiàn)了Copy特征的類(lèi)型(比如:整數(shù)、浮點(diǎn)數(shù)等基本類(lèi)型),插入HashMap時(shí)不會(huì)發(fā)生所有權(quán)轉(zhuǎn)移,而是進(jìn)行值的復(fù)制。

use std::collections::HashMap;

fn main() {
    let mut map = HashMap::new();
    let number: i32 = 66;
    map.insert("Lemon", number);
    
    // 這里仍可以繼續(xù)使用number,因?yàn)閺?fù)制了一份
    println!("{}", number);
}

2、轉(zhuǎn)移所有權(quán)。如果插入到HashMap中的值是不可復(fù)制的類(lèi)型(比如:String或自定義結(jié)構(gòu)體),那么當(dāng)調(diào)用insert方法時(shí),該值的所有權(quán)會(huì)被轉(zhuǎn)移給HashMap。這意味著,原變量將不再有效,并且不能再被使用。

use std::collections::HashMap;

fn main() {
    let mut map = HashMap::new();
    let peach = String::from("Peach");
    // peach的所有權(quán)轉(zhuǎn)移到了HashMap中
    map.insert("Fruit", peach);
    
    // 這里訪(fǎng)問(wèn)peach會(huì)導(dǎo)致編譯錯(cuò)誤,因?yàn)樗呀?jīng)不再擁有所有權(quán)
    // println!("{}", peach);
}

3、引用所有權(quán)。如果想要存儲(chǔ)指向數(shù)據(jù)的引用,而不是數(shù)據(jù)本身,可以使用引用類(lèi)型(比如:&str或&T)。但是,引用的生命周期必須與引用的對(duì)象保持一致,確保在整個(gè)引用存在期間,對(duì)象也依然有效。

use std::collections::HashMap;

fn main() {
    let text = String::from("CSDN");
    let mut map = HashMap::new();
    map.insert("Hello", &text);
    // text必須一直有效,因?yàn)镠ashMap持有對(duì)它的引用
}

到此這篇關(guān)于Rust中HashMap類(lèi)型的使用詳解的文章就介紹到這了,更多相關(guān)Rust HashMap內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • 從零開(kāi)始使用Rust編寫(xiě)nginx(TLS證書(shū)快過(guò)期了)

    從零開(kāi)始使用Rust編寫(xiě)nginx(TLS證書(shū)快過(guò)期了)

    wmproxy已用Rust實(shí)現(xiàn)http/https代理,?socks5代理,?反向代理,?負(fù)載均衡,?靜態(tài)文件服務(wù)器,websocket代理,四層TCP/UDP轉(zhuǎn)發(fā),內(nèi)網(wǎng)穿透等,本文給大家介紹從零開(kāi)始使用Rust編寫(xiě)nginx(TLS證書(shū)快過(guò)期了),感興趣的朋友一起看看吧
    2024-03-03
  • rust閉包的使用

    rust閉包的使用

    閉包在Rust中是非常強(qiáng)大的功能,允許你編寫(xiě)更靈活和表達(dá)性的代碼,本文主要介紹了rust閉包的使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • 通過(guò)rust實(shí)現(xiàn)自己的web登錄圖片驗(yàn)證碼功能

    通過(guò)rust實(shí)現(xiàn)自己的web登錄圖片驗(yàn)證碼功能

    本文介紹了如何使用Rust和imagecrate庫(kù)生成圖像驗(yàn)證碼,首先,通過(guò)Cargo.toml文件添加image依賴(lài),然后,生成純色圖片并編輯驗(yàn)證圖片,接著,編寫(xiě)隨機(jī)函數(shù)獲取字符,并通過(guò)循環(huán)生成驗(yàn)證碼圖片,最終,通過(guò)運(yùn)行函數(shù)驗(yàn)證驗(yàn)證碼圖片是否生成,感興趣的朋友一起看看吧
    2025-03-03
  • Rust日期與時(shí)間的操作方法

    Rust日期與時(shí)間的操作方法

    Rust的時(shí)間操作主要用到chrono庫(kù),接下來(lái)我將簡(jiǎn)單選一些常用的操作進(jìn)行介紹,感興趣的朋友跟隨小編一起看看吧
    2023-09-09
  • Rust讀取配置文件的實(shí)現(xiàn)步驟

    Rust讀取配置文件的實(shí)現(xiàn)步驟

    任何項(xiàng)目都離不開(kāi)對(duì)于配置文件的讀取和解析,rust項(xiàng)目也一樣,本文主要介紹了Rust讀取配置文件的實(shí)現(xiàn)步驟,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • Rust中的Copy和Clone對(duì)比分析

    Rust中的Copy和Clone對(duì)比分析

    這篇文章主要介紹了Rust中的Copy和Clone及區(qū)別對(duì)比分析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • Rust自定義安裝路徑的詳細(xì)圖文教程

    Rust自定義安裝路徑的詳細(xì)圖文教程

    工欲善其事必先利其器,無(wú)論是對(duì)小白還是大神來(lái)說(shuō),想要學(xué)習(xí) Rust 第一步那必須是 Rust 的環(huán)境配置,下面這篇文章主要給大家介紹了關(guān)于Rust自定義安裝路徑的詳細(xì)圖文教程,需要的朋友可以參考下
    2023-03-03
  • Rust?中?Deref?Coercion講解

    Rust?中?Deref?Coercion講解

    Rust 的設(shè)計(jì)理念一向是顯式比隱式好,也就是說(shuō)所有的行為盡量在代碼中表現(xiàn)出來(lái),這篇文章主要介紹了Rust?中?Deref?Coercion?介紹,需要的朋友可以參考下
    2022-10-10
  • Rust使用kind進(jìn)行異常處理(錯(cuò)誤的分類(lèi)與傳遞)

    Rust使用kind進(jìn)行異常處理(錯(cuò)誤的分類(lèi)與傳遞)

    Rust?有一套獨(dú)特的處理異常情況的機(jī)制,它并不像其它語(yǔ)言中的?try?機(jī)制那樣簡(jiǎn)單,這篇文章主要介紹了Rust指南錯(cuò)誤的分類(lèi)與傳遞以及使用kind進(jìn)行異常處理,需要的朋友可以參考下
    2022-09-09
  • 深入了解Rust的生命周期

    深入了解Rust的生命周期

    生命周期指的是引用保持有效的作用域,Rust?的每個(gè)引用都有自己的生命周期。本文將通過(guò)示例和大家詳細(xì)說(shuō)說(shuō)Rust的生命周期,需要的可以參考一下
    2022-11-11

最新評(píng)論