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

Rust字符串類型全解析(最新推薦)

 更新時(shí)間:2024年09月26日 08:57:18   作者:wang_yb  
Rust語(yǔ)言中,字符串類型眾多,設(shè)計(jì)初衷是為了確保程序的安全、高效和靈活性,本文詳細(xì)解釋了Rust中不同的字符串類型,感興趣的朋友跟隨小編一起看看吧

字符串是每種編程語(yǔ)言都繞不開(kāi)的類型,

不過(guò),在Rust中,你會(huì)看到遠(yuǎn)比其他語(yǔ)言更加豐富多樣的字符串類型。

如下圖:

為什么Rust中需要這么多種表示字符串的類型呢?

初學(xué)Rust時(shí),可能無(wú)法理解為什么要這樣設(shè)計(jì)?為什么要給使用字符串帶來(lái)這么多不必要的復(fù)雜性?

其實(shí),Rust中對(duì)于字符串的設(shè)計(jì),優(yōu)先考慮的是安全,高效靈活,

所以在易用性方面,感覺(jué)沒(méi)有其他語(yǔ)言(比如python,golang)那么易于理解和掌握。

本文嘗試解釋Rust中的所有不同的字符串類型,以及它們各自的特點(diǎn)。

希望能讓大家更好的理解Rust為了安全和發(fā)揮最大性能的同時(shí),是如何處理字符串的。

1. 機(jī)器中的字符串

我們代碼中的字符串或者數(shù)字,存儲(chǔ)在機(jī)器中,都是二進(jìn)制,也就是0和1組成的序列。

程序?qū)⒍M(jìn)制數(shù)據(jù)轉(zhuǎn)換為人類可讀的字符串 需要兩個(gè)關(guān)鍵信息:

  • 字符編碼
  • 字符串長(zhǎng)度

常見(jiàn)的編碼有ASCIIUTF-8等等,編碼就是二進(jìn)制序列對(duì)應(yīng)的字符,

比如,ASCII8位二進(jìn)制對(duì)應(yīng)一個(gè)字符,所以它最多只能表示256種不同的字符。

UTF-8可以使用8位~32位二進(jìn)制來(lái)表示一個(gè)字符,這意味著它可以編碼超過(guò)一百萬(wàn)個(gè)字符,

包括世界上的每種語(yǔ)言和各種表情符號(hào)等復(fù)雜字符。

通過(guò)字符編碼,我們可以將二進(jìn)制和字符互相轉(zhuǎn)換,

再通過(guò)字符串長(zhǎng)度信息,我們將內(nèi)存中的二進(jìn)制轉(zhuǎn)換為字符串時(shí),就能知道何時(shí)停止。

Rust中的字符串,統(tǒng)一采用UTF-8編碼,下面一一介紹各種字符串類型及其使用場(chǎng)景。

2. String 和 &str

String&strRust中使用最多的兩種字符串類型,也是在使用中容易混淆的兩種類型。

String是分配在堆上的,可增長(zhǎng)的UTF-8字符串,

它擁有底層的數(shù)據(jù),并且在超出其定義的范圍被自動(dòng)清理釋放。

let my_string = String::from("databook");
println!(
    "pointer: {:p}, length: {}, capacity: {}",
    &my_string,
    my_string.len(),
    my_string.capacity()
);

對(duì)于一個(gè)String,主要部分有3個(gè):

  • Pointer:指向堆內(nèi)存中字符串的起始位置
  • Length:有效字符串的長(zhǎng)度
  • Capacity:字符串my_string總共占用的空間

注意這里LengthCapacity的區(qū)別,Lengthmy_string中有效字符的長(zhǎng)度,也就是字符串實(shí)際的長(zhǎng)度;

Capacity表示系統(tǒng)為my_string分配的內(nèi)存空間,一般來(lái)說(shuō),Capacity >= Length。

通常不需要直接處理Capacity,但它的存在對(duì)于編寫高效且資源敏感的Rust代碼時(shí)很重要。

特別是,當(dāng)你知道即將向String添加大量?jī)?nèi)容時(shí),可能會(huì)事先手動(dòng)保留足夠的Capacity以避免多次內(nèi)存重新分配。

&str則是一個(gè)字符串的切片,它表示一個(gè)連續(xù)的字符序列,

它是一個(gè)借用類型,并不擁有字符串?dāng)?shù)據(jù),只包含指向切片開(kāi)頭的指針和切片長(zhǎng)度。

let my_str: &str = "databook";
println!("pointer: {:p}, length: {}", &my_str, my_str.len());

注意,&str沒(méi)有Capacity方法,因?yàn)樗皇且粋€(gè)借用,內(nèi)容不可能增加。

最后,對(duì)于String&str,使用時(shí)建議:

  • 在運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建或修改字符串?dāng)?shù)據(jù)時(shí),請(qǐng)使用 String
  • 讀取或分析字符串?dāng)?shù)據(jù)而不對(duì)其進(jìn)行更改時(shí),請(qǐng)使用 &str

3. Vec[u8] 和 &[u8]

這兩種形式是將字符串表示位字節(jié)的形式,其中Vec[u8]是字節(jié)向量,&[u8]是字節(jié)切片。

它們只是將字符串中的各個(gè)字符轉(zhuǎn)換成字節(jié)形式。

as_bytes方法可將&str轉(zhuǎn)換為&[u8];

into_bytes方法可將String轉(zhuǎn)換為Vec<u8>。

let my_str: &str = "databook";
let my_string = String::from("databook");
let s: &[u8] = my_str.as_bytes();
let ss: Vec<u8> = my_string.into_bytes();
println!("s: {:?}", s);
println!("ss: {:?}", ss);
/* 運(yùn)行結(jié)果
s: [100, 97, 116, 97, 98, 111, 111, 107]
ss: [100, 97, 116, 97, 98, 111, 111, 107]
*/

在UTF-8編碼中,每個(gè)英文字母對(duì)應(yīng)1個(gè)字節(jié),而一個(gè)中文漢字對(duì)應(yīng)3個(gè)字節(jié)。

let my_str: &str = "中文";
let my_string = String::from("中文");
let s: &[u8] = my_str.as_bytes();
let ss: Vec<u8> = my_string.into_bytes();
println!("s: {:?}", s);
println!("ss: {:?}", ss);
/* 運(yùn)行結(jié)果
s: [228, 184, 173, 230, 150, 135]
ss: [228, 184, 173, 230, 150, 135]
*/

Vec[u8]&[u8]以字節(jié)的形式存儲(chǔ)字符串,不用關(guān)心字符串的具體編碼,

這在網(wǎng)絡(luò)中傳輸二進(jìn)制文件或者數(shù)據(jù)包時(shí)非常有用,可以有效每次傳輸多少個(gè)字節(jié)。

4. str 系列

str類型本身是不能直接使用的,因?yàn)樗拇笮≡诰幾g期無(wú)法確定,不符合Rust的安全規(guī)則。

但是,它可以與其他具有特殊用途的指針類型一起使用。

4.1. Box<str>

如果需要一個(gè)字符串切片的所有權(quán)(&str是借用的,沒(méi)有所有權(quán)),那么可以使用Box智能指針。

當(dāng)你想要凍結(jié)字符串以防止進(jìn)一步修改或通過(guò)刪除額外容量來(lái)節(jié)省內(nèi)存時(shí),它非常有用。

比如,下面的代碼,我們將一個(gè)String轉(zhuǎn)換為Box<str>

這樣,可以確保它不會(huì)在其他地方被修改,也可以刪除它,因?yàn)?code>Box<str>擁有字符串的所有權(quán)。

let my_string = String::from("databook");
let my_box_str = my_string.into_boxed_str();
println!("{}", my_box_str);
// 這一步會(huì)報(bào)錯(cuò),因?yàn)樗袡?quán)已經(jīng)轉(zhuǎn)移
// 這是 Box<str> 和 &str 的區(qū)別
// println!("{}", my_string);

4.2. Rc<str>

當(dāng)你想要在多個(gè)地方共享一個(gè)不可變的字符串的所有權(quán),但是又不克隆實(shí)際的字符串?dāng)?shù)據(jù)時(shí),

可以嘗試使用Rc<str>智能指針。

比如,我們有一個(gè)非常大的文本,想在多個(gè)地方使用,又不想復(fù)制多份占用內(nèi)存,可以用Rc<str>

let my_str: &str = "very long text ....";
let rc_str1: Rc<str> = Rc::from(my_str);
let rc_str2 = Rc::clone(&rc_str1);
let rc_str3 = Rc::clone(&rc_str1);
println!("rc_str1: {}", rc_str1);
println!("rc_str2: {}", rc_str2);
println!("rc_str3: {}", rc_str3);
/* 運(yùn)行結(jié)果
rc_str1: very long text ....
rc_str2: very long text ....
rc_str3: very long text ....
*/

這樣,在不實(shí)際克隆字符串?dāng)?shù)據(jù)的情況下,讓多個(gè)變量擁有其所有權(quán)。

4.3. Arc<str>

Arc<str>Rc<str>的功能類似,主要的區(qū)別在于Arc<str>是線程安全的。

如果在多線程環(huán)境下,請(qǐng)使用Arc<str>。

let my_str: &str = "very long text ....";
let arc_str: Arc<str> = Arc::from(my_str);
let mut threads = vec![];
let mut cnt = 0;
while cnt < 5 {
    let s = Arc::clone(&arc_str);
    let t = thread::spawn(move || {
        println!("thread-{}: {}", cnt, s);
    });
    threads.push(t);
    cnt += 1;
}
for t in threads {
    t.join().unwrap();
}
/* 運(yùn)行結(jié)果
thread-0: very long text ....
thread-3: very long text ....
thread-2: very long text ....
thread-1: very long text ....
thread-4: very long text ....
*/

上面的代碼中,在5個(gè)線程中共享了字符串?dāng)?shù)據(jù)。

上面運(yùn)行結(jié)果中,線程順序是不固定的,多執(zhí)行幾遍會(huì)有不一樣的順序。

4.4. Cow<str>

CowCopy-on-Write(寫入時(shí)復(fù)制)的縮寫,

當(dāng)你需要實(shí)現(xiàn)一個(gè)功能,根據(jù)字符串的內(nèi)容來(lái)決定是否需要修改它,使用Cow就很合適。

比如,過(guò)濾敏感詞匯時(shí),我們把敏感詞匯替換成xx。

fn filter_words(input: &str) -> Cow<str> {
    if input.contains("sb") {
        let output = input.replace("sb", "xx");
        return Cow::Owned(output);
    }
    Cow::Borrowed(input)
}

當(dāng)輸入字符串input中含有敏感詞sb時(shí),會(huì)重新分配內(nèi)存,生成新字符串;

否則直接使用原字符串,提高內(nèi)存效率。

5. CStr 和 CString

CStrCString是與C語(yǔ)言交互時(shí)用于處理字符串的兩種類型。

CStr用于在Rust中安全地訪問(wèn)由C語(yǔ)言分配的字符串;

CString用于在Rust中創(chuàng)建和管理可以安全傳遞給C語(yǔ)言函數(shù)的字符串。

C風(fēng)格的字符串與Rust中的字符串實(shí)現(xiàn)方式不一樣,

比如,C語(yǔ)言中的字符串都是以null字符\0結(jié)尾的字節(jié)數(shù)組,這點(diǎn)就與Rust很不一樣。

所以Rust單獨(dú)封裝了這兩種類型(CStrCString),可以安全的與C語(yǔ)言進(jìn)行字符串交互,從而實(shí)現(xiàn)與現(xiàn)有的C語(yǔ)言庫(kù)和API無(wú)縫集成。

6. OsStr 和 OsString

OsStr 和 OsString 是用于處理與操作系統(tǒng)兼容的字符串類型。

主要用于需要與操作系統(tǒng)API進(jìn)行交互的場(chǎng)景,這些API一般特定于平臺(tái)的字符串編碼(比如Windows上的UTF-16,以及大多數(shù)Unix-like系統(tǒng)上的UTF-8)。

OsStr 和OsString 也相當(dāng)于strString的關(guān)系,所以OsStr 一般不直接在代碼中使用,

使用比較多的是&OsStrOsString。

這兩個(gè)類型一般用于讀取/寫入操作系統(tǒng)環(huán)境變量或者與系統(tǒng)API交互時(shí),幫助我們確保字符串以正確的格式傳遞。

7. Path 和 PathBuf

這兩個(gè)類型看名字似乎和字符串關(guān)系不大,實(shí)際上它們是專門用來(lái)處理文件路徑字符串的。

在不同的文件系統(tǒng)中,對(duì)于文件路徑的格式,路徑中允許使用的字符都不一樣,比如,windows系統(tǒng)中文件路徑甚至不區(qū)分大小寫。

使用Path 和 PathBuf,我們編碼時(shí)就不用分散精力去關(guān)心具體使用的是哪種文件系統(tǒng)。

PathPathBuf的主要區(qū)別在于可變性和所有權(quán),

如果需要頻繁讀取和查詢路徑信息而不修改它,Path是一個(gè)好選擇;

如果需要?jiǎng)討B(tài)構(gòu)建或修改路徑內(nèi)容,PathBuf則更加合適。

8. 總結(jié)

總之,Rust中字符串類型之所以多,是因?yàn)楦鶕?jù)不同的用途對(duì)字符串類型做了分類。

這也是為了處理不同的應(yīng)用場(chǎng)景時(shí)讓程序發(fā)揮最大的性能,畢竟,安全高性能一直是Rust最大的賣點(diǎn)。

到此這篇關(guān)于Rust字符串類型全解析(最新推薦)的文章就介紹到這了,更多相關(guān)Rust字符串類型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Rust中類型轉(zhuǎn)換在錯(cuò)誤處理中的應(yīng)用小結(jié)

    Rust中類型轉(zhuǎn)換在錯(cuò)誤處理中的應(yīng)用小結(jié)

    隨著項(xiàng)目的進(jìn)展,關(guān)于Rust的故事又翻開(kāi)了新的一頁(yè),今天來(lái)到了服務(wù)器端的開(kāi)發(fā)場(chǎng)景,發(fā)現(xiàn)錯(cuò)誤處理中的錯(cuò)誤類型轉(zhuǎn)換有必要分享一下,對(duì)Rust錯(cuò)誤處理相關(guān)知識(shí)感興趣的朋友一起看看吧
    2023-09-09
  • 淺談Rust?+=?運(yùn)算符與?MIR?應(yīng)用

    淺談Rust?+=?運(yùn)算符與?MIR?應(yīng)用

    這篇文章主要介紹了Rust?+=?運(yùn)算符與?MIR?應(yīng)用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-01-01
  • rust中的match表達(dá)式使用詳解

    rust中的match表達(dá)式使用詳解

    在rust中提供了一個(gè)極為強(qiáng)大的控制流運(yùn)算符match,這篇文章主要介紹了rust中的match表達(dá)式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • Go調(diào)用Rust方法及外部函數(shù)接口前置

    Go調(diào)用Rust方法及外部函數(shù)接口前置

    這篇文章主要為大家介紹了Go調(diào)用Rust方法及外部函數(shù)接口前置示例實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Rust 入門之函數(shù)和注釋實(shí)例詳解

    Rust 入門之函數(shù)和注釋實(shí)例詳解

    這篇文章主要為大家介紹了Rust 入門之函數(shù)和注釋實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Rust語(yǔ)言數(shù)據(jù)類型的具體使用

    Rust語(yǔ)言數(shù)據(jù)類型的具體使用

    在Rust中,每個(gè)值都有一個(gè)明確的數(shù)據(jù)類型,本文主要介紹了Rust語(yǔ)言數(shù)據(jù)類型的具體使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-04-04
  • 詳解Rust 生命周期符號(hào)使用的方法和規(guī)律

    詳解Rust 生命周期符號(hào)使用的方法和規(guī)律

    生命周期是 Rust 中處理引用和所有權(quán)的關(guān)鍵概念,通過(guò)正確使用生命周期符號(hào)和遵循相關(guān)規(guī)律,你可以編寫出安全、高效的 Rust 代碼,這篇文章主要介紹了Rust 生命周期符號(hào)使用的方法和規(guī)律,需要的朋友可以參考下
    2024-03-03
  • Rust開(kāi)發(fā)環(huán)境搭建到運(yùn)行第一個(gè)程序HelloRust的圖文教程

    Rust開(kāi)發(fā)環(huán)境搭建到運(yùn)行第一個(gè)程序HelloRust的圖文教程

    本文主要介紹了Rust開(kāi)發(fā)環(huán)境搭建到運(yùn)行第一個(gè)程序HelloRust的圖文教程,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-12-12
  • Rust循環(huán)控制結(jié)構(gòu)用法詳解

    Rust循環(huán)控制結(jié)構(gòu)用法詳解

    Rust提供了多種形式的循環(huán)結(jié)構(gòu),每種都適用于不同的場(chǎng)景,在Rust中,循環(huán)有三種主要的形式:loop、while和for,本文將介紹Rust中的這三種循環(huán),并通過(guò)實(shí)例展示它們的用法和靈活性,感興趣的朋友一起看看吧
    2024-02-02
  • Rust聲明宏在不同K線bar類型中的應(yīng)用小結(jié)

    Rust聲明宏在不同K線bar類型中的應(yīng)用小結(jié)

    在K線bar中,往往有很多不同分時(shí)k線圖,比如1,2,3,5,,,,,60,120,250,300…,,不同分鐘類型,如果不用宏,那么手寫會(huì)比較麻煩,下面就試用一下宏來(lái)實(shí)現(xiàn)不同類型的bar,感興趣的朋友一起看看吧
    2024-05-05

最新評(píng)論