最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Rust語(yǔ)言中的String和HashMap使用示例詳解

 更新時(shí)間:2022年10月18日 15:47:50   作者:SaraiNoQ  
這篇文章主要介紹了Rust語(yǔ)言中的String和HashMap使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

String

字符串是比很多開(kāi)發(fā)者所理解的更為復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。加上 UTF-8 的不定長(zhǎng)編碼等原因,Rust 中的字符串并不如其它語(yǔ)言中那么好理解。

Rust 的核心語(yǔ)言中只有一種字符串類型:str。字符串 slice,它通常以被借用的形式出現(xiàn):&str 是一些儲(chǔ)存在別處的 UTF-8 編碼字符串?dāng)?shù)據(jù)的引用。而 String 的類型是由標(biāo)準(zhǔn)庫(kù)提供的,而沒(méi)有寫(xiě)進(jìn)核心語(yǔ)言部分,它是可增長(zhǎng)的、可變的、有所有權(quán)的、UTF-8 編碼的字符串類型。

?? Rust 標(biāo)準(zhǔn)庫(kù)中還包含一系列其他字符串類型,比如 OsString、OsStrCStringCStr。相關(guān)庫(kù) crate 還會(huì)提供更多儲(chǔ)存字符串?dāng)?shù)據(jù)的數(shù)據(jù)類型。這些字符串類型能夠以不同的編碼,或者內(nèi)存表現(xiàn)形式上以不同的形式,來(lái)存儲(chǔ)文本內(nèi)容。

新建字符串

  • String::new()函數(shù)
  • to_string()方法
let data = "initial contents";
let s = data.to_string();
// 或者
let s = String::from(data);
// 該方法也可直接用于字符串字面量:
let s = "initial contents".to_string();

更新字符串

String 的大小可以增加,其內(nèi)容也可以改變。另外,還可以使用 + 運(yùn)算符或 format! 宏來(lái)拼接 String 值。

  • push_str()
  • push()
let mut s = String::from("foo");
let t = String::from("bar");
s.push_str(&t);
// push 方法被定義為獲取一個(gè)單獨(dú)的字符作為參數(shù),并附加到 String 中
let mut l = String::from("lo");
l.push('l');

?? pub fn push_str(&mut self, string: &str) 方法不會(huì)獲得字符串的所有權(quán)。另外值得一提的是,t&String 類型,而 push_str 方法需要的是 &str 類型的參數(shù)。為什么這段代碼能夠正常編譯呢?這里就涉及到了 解引用強(qiáng)制轉(zhuǎn)換(deref coercion),我們將在后面的文章中介紹它。

使用 + 運(yùn)算符或 format! 宏拼接字符串

let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2;

你可以把他理解成 C++ 的運(yùn)算符重載。在 Rust 中, + 的實(shí)現(xiàn)可能是 fn add(self, s: &str) -> String 這樣一個(gè)方法。

?? s1 的所有權(quán)將被移動(dòng)到 add 調(diào)用中

如果想要級(jí)聯(lián)多個(gè)字符串,使用 + 就變得麻煩了。這時(shí)候可以使用 format! 宏:

let s1 = String::from("hello");
let s2 = String::from("the");
let s3 = String::from("world");
let s = format!("{}-{}-{}", s1, s2, s3);

索引字符串

在其他語(yǔ)言中,通過(guò)索引來(lái)引用字符串中的某個(gè)單獨(dú)字符是很常見(jiàn)的操作。但在 Rust 中,你可能會(huì)遇到問(wèn)題:

這主要是因?yàn)椋?/p>

  • UTF-8 是不定長(zhǎng)編碼,而 String 的實(shí)現(xiàn)是基于 Vec<u8> 的封裝:數(shù)組中每一個(gè)元素都是一個(gè)字節(jié),但 UTF-8 中每一個(gè)漢字(或字符)都可能由一到四個(gè)字節(jié)組成
  • 索引操作預(yù)期總是需要常數(shù)時(shí)間 (O(1))。但是對(duì)于 String 不可能保證這樣的性能,因?yàn)?Rust 必須從開(kāi)頭到索引位置遍歷來(lái)確定有多少有效的字符。

字符串 slice

如果你真的希望使用索引創(chuàng)建字符串 slice 時(shí),Rust 會(huì)要求你明確字符串范圍。這時(shí)你需要一個(gè)字符串 slice,使用 [] 和一個(gè) range 來(lái)創(chuàng)建含特定字節(jié)的字符串 slice:

fn main() {
    let s1 = String::from("你好,");
    println!("{}", &s1[0..3]);  // 你
}

如果獲取 &s1[0..1] ,Rust 在運(yùn)行時(shí)會(huì) panic。因此,你應(yīng)該謹(jǐn)慎地使用這個(gè)操作,因?yàn)檫@么做可能會(huì)使你的程序崩潰。

遍歷字符串

可以使用 chars() 方法獲取該字符串的字母數(shù)組。

fn main() {
    let s1 = String::from("你好,");
    let s2 = String::from("世界!");
    let s3 = s1 + &s2; 
    for char in s3.chars() {
        println!("{}", char);
    }
}

HashMap

另外一個(gè)常用集合類型是 哈希 map(hash map)。HashMap<K, V> 類型儲(chǔ)存了一個(gè)鍵類型 K 對(duì)應(yīng)一個(gè)值類型 V 的映射。它通過(guò)一個(gè) 哈希函數(shù)(hashing function)來(lái)實(shí)現(xiàn)映射,決定如何將鍵和值放入內(nèi)存中。

哈希 map 適用于需要任何類型作為鍵來(lái)尋找數(shù)據(jù)的情況,而不是像 vector 那樣通過(guò)索引。

新建 HashMap

使用new 創(chuàng)建一個(gè)空的 HashMap,并使用 insert 增加元素:

use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);

?? 必須首先 use 標(biāo)準(zhǔn)庫(kù)中集合部分的 HashMap。在這上面介紹的三個(gè)常用集合中,HashMap 是最不常用的,所以并沒(méi)有被 prelude 自動(dòng)引用。標(biāo)準(zhǔn)庫(kù)中對(duì) HashMap 的支持也相對(duì)較少,例如,并沒(méi)有內(nèi)建的構(gòu)建宏。

?? 像 vector 一樣,哈希 map 將它們的數(shù)據(jù)儲(chǔ)存在堆上;哈希 map 是同質(zhì)的:所有的鍵必須是相同類型,值也必須都是相同類型。

另一個(gè)構(gòu)建哈希 map 的方法是使用一個(gè)元組的 vector 的 collect 方法:

use std::collections::HashMap;
let teams  = vec![String::from("Blue"), String::from("Yellow")];
let initial_scores = vec![10, 50];
let scores: HashMap<_, _> = teams.iter().zip(initial_scores.iter()).collect();

HashMap 和 ownership

  • 對(duì)于像 i32 這樣的實(shí)現(xiàn)了 Copy trait 的類型,其值可以拷貝進(jìn)哈希 map。
  • 對(duì)于像 String 這樣擁有所有權(quán)的值,其值將被移動(dòng)而哈希 map 會(huì)成為這些值的所有者。
use std::collections::HashMap;
let field_name = String::from("Favorite color");
let field_value = String::from("Blue");
let mut map = HashMap::new();
map.insert(field_name, field_value);
// 此時(shí) field_name 和 field_value 被移動(dòng)到了 map 中

?? 如果將值的引用插入哈希 map,這些值本身將不會(huì)被移動(dòng)進(jìn)哈希 map。但是這些引用指向的值必須至少在哈希 map 有效時(shí)也是有效的。此時(shí)就涉及到生命周期的內(nèi)容。

訪問(wèn) HashMap 中的值

可以通過(guò) get 方法并提供對(duì)應(yīng)的鍵來(lái)從哈希 map 中獲取值:

use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
let team_name = String::from("Blue");
let score = scores.get(&team_name);

get 返回 Option<V>,所以結(jié)果被裝進(jìn) Some;如果某個(gè)鍵在哈希 map 中沒(méi)有對(duì)應(yīng)的值,get 會(huì)返回 None。當(dāng)獲取到結(jié)果后,就需要使用到 match 進(jìn)行匹配。

更新 HashMap

在更新前,我們需要考慮以下幾種情況:

  • 已有 key-value,直接覆蓋
  • 只在沒(méi)有 key-value 時(shí)插入
  • 利用已有 key-value 來(lái) 更新

直接覆蓋

insert() 方法:

use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Blue"), 25);
println!("{:?}", scores);

新插入

利用 entry() 函數(shù)返回的枚舉值,調(diào)用 or_insert() 方法進(jìn)行處理:

use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.entry(String::from("Yellow")).or_insert(50);
scores.entry(String::from("Blue")).or_insert(50);
println!("{:?}", scores);

?? Entryor_insert 方法在鍵對(duì)應(yīng)的值存在時(shí)就返回這個(gè)值的可變引用,如果不存在則將參數(shù)作為新值插入并返回新值的可變引用。

更新舊值

or_insert 方法事實(shí)上會(huì)返回這個(gè)鍵的值的一個(gè)可變引用(&mut V):

// 統(tǒng)計(jì)字符串中某個(gè)單詞的出現(xiàn)次數(shù)
use std::collections::HashMap;
let text = "hello world wonderful world";
let mut map = HashMap::new();
for word in text.split_whitespace() {
    let count = map.entry(word).or_insert(0); // 之前不存在對(duì)應(yīng)關(guān)系就初始化并置計(jì)數(shù)器為0
    *count += 1; // 每次計(jì)數(shù)器加一
}
println!("{:?}", map);

?? 這里我們將這個(gè)可變引用儲(chǔ)存在 count 變量中,所以為了賦值必須首先使用星號(hào)( * )解引用 count。這個(gè)可變引用在 for 循環(huán)的結(jié)尾離開(kāi)作用域,這樣所有這些改變都是安全的并符合借用規(guī)則。

總結(jié)

掌握了 Rust 中最常用的三種集合類型,現(xiàn)在你已經(jīng)可以開(kāi)始進(jìn)行一些包含復(fù)雜邏輯的編程了!在此過(guò)程中你可能會(huì)遇到很多錯(cuò)誤。因此接下來(lái)我將介紹錯(cuò)誤處理與模式匹配,并開(kāi)始介紹一些測(cè)試工具和自動(dòng)化測(cè)試的內(nèi)容,更多關(guān)于Rust String HashMap使用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

  • rust的vector和hashmap詳解

    rust的vector和hashmap詳解

    這篇文章主要介紹了rust的vector和hashmap,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • Rust并發(fā)編程之使用消息傳遞進(jìn)行線程間數(shù)據(jù)共享方式

    Rust并發(fā)編程之使用消息傳遞進(jìn)行線程間數(shù)據(jù)共享方式

    文章介紹了Rust中的通道(channel)概念,包括通道的基本概念、創(chuàng)建并使用通道、通道與所有權(quán)、發(fā)送多個(gè)消息以及多發(fā)送端,通道提供了一種線程間安全的通信機(jī)制,通過(guò)所有權(quán)規(guī)則確保數(shù)據(jù)安全,并且支持多生產(chǎn)者單消費(fèi)者架構(gòu)
    2025-02-02
  • Rust語(yǔ)言之trait中的個(gè)方法可以重寫(xiě)嗎

    Rust語(yǔ)言之trait中的個(gè)方法可以重寫(xiě)嗎

    在Rust中,trait定義了一組方法,這些方法可以被一個(gè)或多個(gè)類型實(shí)現(xiàn),當(dāng)你為某個(gè)類型實(shí)現(xiàn)一個(gè)trait時(shí),你可以為該trait中的每個(gè)方法提供自己的具體實(shí)現(xiàn),本文將給大家介紹一下trait中的個(gè)方法是否可以重寫(xiě),需要的朋友可以參考下
    2023-10-10
  • Rust?實(shí)現(xiàn)?async/await的詳細(xì)代碼

    Rust?實(shí)現(xiàn)?async/await的詳細(xì)代碼

    異步編程在 Rust 中的地位非常高,很多 crate 尤其是多IO操作的都使用了 async/await,這篇文章主要介紹了Rust?如何實(shí)現(xiàn)?async/await,需要的朋友可以參考下
    2022-09-09
  • Rust語(yǔ)言的新手了解和學(xué)習(xí)入門(mén)啟蒙教程

    Rust語(yǔ)言的新手了解和學(xué)習(xí)入門(mén)啟蒙教程

    這篇文章主要介紹了rust的特點(diǎn)、安裝、項(xiàng)目結(jié)構(gòu)、IDE環(huán)境配置、代碼運(yùn)行,講解了如何安裝Rust編譯器,創(chuàng)建和運(yùn)行第一個(gè)Rust程序,并對(duì)Rust語(yǔ)言的特點(diǎn)和優(yōu)勢(shì)作了說(shuō)明,包括內(nèi)存安全、高效性能、并發(fā)性、社區(qū)支持和統(tǒng)一包管理等,是新手了解和學(xué)習(xí)Rust語(yǔ)言的啟蒙教程
    2024-12-12
  • rust中間件actix_web在項(xiàng)目中的使用實(shí)戰(zhàn)

    rust中間件actix_web在項(xiàng)目中的使用實(shí)戰(zhàn)

    這篇文章主要介紹了rust中間件在項(xiàng)目中的使用實(shí)戰(zhàn),包括自定義中間件,日志中間件,Default?headers,用戶會(huì)話,錯(cuò)誤處理的用法實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Rust中的關(guān)聯(lián)類型總結(jié)

    Rust中的關(guān)聯(lián)類型總結(jié)

    關(guān)聯(lián)類型是定義通用trait的一種機(jī)制。它允許在trait中定義一個(gè)或多個(gè)占位符類型,這些類型將在trait的實(shí)現(xiàn)中具體化。文中有詳細(xì)示例代碼供參考,需要的朋友可以閱讀一下
    2023-05-05
  • 詳解Rust中的所有權(quán)機(jī)制

    詳解Rust中的所有權(quán)機(jī)制

    Rust?語(yǔ)言提供了跟其他系統(tǒng)編程語(yǔ)言相同的方式來(lái)控制你使用的內(nèi)存,但擁有數(shù)據(jù)所有者在離開(kāi)作用域后自動(dòng)清除其數(shù)據(jù)的功能意味著你無(wú)須額外編寫(xiě)和調(diào)試相關(guān)的控制代碼,這篇文章主要介紹了Rust中的所有權(quán)機(jī)制,需要的朋友可以參考下
    2022-10-10
  • rust中async/await的使用示例詳解

    rust中async/await的使用示例詳解

    在Rust中,async/await用于編寫(xiě)異步代碼,使得異步操作更易于理解和編寫(xiě),通過(guò)使用await,在async函數(shù)或代碼塊中等待Future完成,而不會(huì)阻塞線程,允許同時(shí)執(zhí)行其他Future,這種機(jī)制簡(jiǎn)化了異步編程的復(fù)雜性,使代碼更加直觀
    2024-10-10
  • 最新評(píng)論

    康平县| 海盐县| 贺兰县| 巴中市| 清水河县| 阜平县| 武冈市| 清新县| 平谷区| 交口县| 阳城县| 盐池县| 潞西市| 涪陵区| 泰宁县| 盘山县| 芒康县| 邓州市| 井研县| 饶河县| 玉屏| 信宜市| 德江县| 商丘市| 九江县| 浑源县| 道孚县| 明光市| 寿阳县| 九龙城区| 科技| 绿春县| 张家港市| 扶风县| 德清县| 泾川县| 通化市| 兴海县| 卓资县| 青州市| 蓬溪县|