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

Rust中字符串String集合的具有使用

 更新時(shí)間:2024年04月19日 11:32:03   作者:Y小夜  
在Rust中,字符串方法主要位于標(biāo)準(zhǔn)庫(kù)的std::string模塊中,這些方法可以幫助我們處理字符串的常見(jiàn)操作,本文主要介紹了Rust中字符串String集合的具有使用,具有一定的參考價(jià)值,感興趣的可以了解一下

Rust開(kāi)發(fā)者經(jīng)常被字符串困擾的原因

  • 傾向于確保暴露出可能的錯(cuò)誤。
  • 字符串是比很多程序員所想象的要更為復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。
  • UTF-8。

字符串是什么

Rust 的核心語(yǔ)言中只有一種字符串類型:字符串 slice str,它通常以被借用的形式出現(xiàn),&str。

字符串(String)類型由 Rust 標(biāo)準(zhǔn)庫(kù)提供,而不是編入核心語(yǔ)言,它是一種可增長(zhǎng)、可變、可擁有、UTF-8 編碼的字符串類型。當(dāng) Rustaceans 提及 Rust 中的 "字符串 "時(shí),他們可能指的是 String 或 string slice &str 類型,而不僅僅是其中一種類型。

創(chuàng)建字符串

很多 Vec 可用的操作在 String 中同樣可用,事實(shí)上 String 被實(shí)現(xiàn)為一個(gè)帶有一些額外保證、限制和功能的字節(jié) vector 的封裝。其中一個(gè)同樣作用于 Vec<T> 和 String 函數(shù)的例子是用來(lái)新建一個(gè)實(shí)例的 new 函數(shù)

let mut s = String::new();

這新建了一個(gè)叫做 s 的空的字符串,接著我們可以向其中裝載數(shù)據(jù)。通常字符串會(huì)有初始數(shù)據(jù),因?yàn)槲覀兿M婚_(kāi)始就有這個(gè)字符串。為此,可以使用 to_string 方法,它能用于任何實(shí)現(xiàn)了 Display trait 的類型,比如字符串字面值。

let data = "initial contents";
let s = data.to_string();
    // 該方法也可直接用于字符串字面值:
    let s = "initial contents".to_string();

因?yàn)樽址畱?yīng)用廣泛,這里有很多不同的用于字符串的通用 API 可供選擇。其中一些可能看起來(lái)多余,不過(guò)都有其用武之地!在這個(gè)例子中,String::from 和 .to_string 最終做了完全相同的工作,所以如何選擇就是代碼風(fēng)格與可讀性的問(wèn)題了。

let s = String::from("initial contents");

記住字符串是 UTF-8 編碼的,所以可以包含任何可以正確編碼的數(shù)據(jù)

    let hello = String::from("?????? ?????");
    let hello = String::from("Dobry den");
    let hello = String::from("Hello");
    let hello = String::from("???????");
    let hello = String::from("??????");
    let hello = String::from("こんにちは");
    let hello = String::from("?????");
    let hello = String::from("你好");
    let hello = String::from("Olá");
    let hello = String::from("Здравствуйте");
    let hello = String::from("Hola");

更新String

String 的大小可以增加,其內(nèi)容也可以改變,就像可以放入更多數(shù)據(jù)來(lái)改變 Vec 的內(nèi)容一樣。另外,可以方便的使用 + 運(yùn)算符或 format! 宏來(lái)拼接 String 值。

使用push_str和push附加字符串

可以通過(guò) push_str 方法來(lái)附加字符串 slice,從而使 String 變長(zhǎng):

    let mut s = String::from("foo");
    s.push_str("bar");

執(zhí)行這兩行代碼之后,s 將會(huì)包含 foobar。push_str 方法采用字符串 slice,因?yàn)槲覀儾⒉恍枰@取參數(shù)的所有權(quán)。

    let mut s1 = String::from("foo");
    let s2 = "bar";
    s1.push_str(s2);
    println!("s2 is {s2}");

push 方法被定義為獲取一個(gè)單獨(dú)的字符作為參數(shù),并附加到 String 中。

    let mut s = String::from("lo");
    s.push('l');

如何拼接字符串

    let s1 = String::from("Hello, ");
    let s2 = String::from("world!");
    let s3 = s1 + &s2; // 注意 s1 被移動(dòng)了,不能繼續(xù)使用

執(zhí)行完這些代碼之后,字符串 s3 將會(huì)包含 Hello, world!s1 在相加后不再有效的原因,和使用 s2 的引用的原因,與使用 + 運(yùn)算符時(shí)調(diào)用的函數(shù)簽名有關(guān)。+ 運(yùn)算符使用了 add 函數(shù),這個(gè)函數(shù)簽名看起來(lái)像這樣:

fn add(self, s: &str) -> String {

解釋:s2 使用了 &,意味著我們使用第二個(gè)字符串的 引用 與第一個(gè)字符串相加。這是因?yàn)?nbsp;add 函數(shù)的 s 參數(shù):只能將 &str 和 String 相加,不能將兩個(gè) String 值相加。不過(guò)等一下 —— &s2 的類型是 &String, 而不是 add 第二個(gè)參數(shù)所指定的 &str

如果想要級(jí)聯(lián)多個(gè)字符串,+ 的行為就顯得笨重了:

    let s1 = String::from("tic");
    let s2 = String::from("tac");
    let s3 = String::from("toe");

    let s = s1 + "-" + &s2 + "-" + &s3;

這時(shí) s 的內(nèi)容會(huì)是 “tic-tac-toe”。在有這么多 + 和 " 字符的情況下,很難理解具體發(fā)生了什么。對(duì)于更為復(fù)雜的字符串鏈接,可以使用 format! 宏:

    let s1 = String::from("tic");
    let s2 = String::from("tac");
    let s3 = String::from("toe");

    let s = format!("{s1}-{s2}-{s3}");

索引字符串

在很多語(yǔ)言中,通過(guò)索引來(lái)引用字符串中的單獨(dú)字符是有效且常見(jiàn)的操作。然而在 Rust 中,如果你嘗試使用索引語(yǔ)法訪問(wèn) String 的一部分,會(huì)出現(xiàn)一個(gè)錯(cuò)誤。

    let s1 = String::from("hello");
    let h = s1[0];

錯(cuò)誤和提示說(shuō)明了全部問(wèn)題:Rust 的字符串不支持索引。那么接下來(lái)的問(wèn)題是,為什么不支持呢?為了回答這個(gè)問(wèn)題,我們必須先聊一聊 Rust 是如何在內(nèi)存中儲(chǔ)存字符串的。

內(nèi)部表示

String 是一個(gè) Vec<u8> 的封裝。

let hello = String::from("Hola");

在這里,len 的值是 4,這意味著儲(chǔ)存字符串 “Hola” 的 Vec 的長(zhǎng)度是四個(gè)字節(jié):這里每一個(gè)字母的 UTF-8 編碼都占用一個(gè)字節(jié)。那下面這個(gè)例子又如何呢?(注意這個(gè)字符串中的首字母是西里爾字母的 Ze 而不是數(shù)字 3。

let hello = String::from("Здравствуйте");

我們已經(jīng)知道 answer 不是第一個(gè)字符 3。當(dāng)使用 UTF-8 編碼時(shí),(西里爾字母的 Ze)З 的第一個(gè)字節(jié)是 208,第二個(gè)是 151,所以 answer 實(shí)際上應(yīng)該是 208,不過(guò) 208 自身并不是一個(gè)有效的字母。返回 208 可不是一個(gè)請(qǐng)求字符串第一個(gè)字母的人所希望看到的,不過(guò)它是 Rust 在字節(jié)索引 0 位置所能提供的唯一數(shù)據(jù)。用戶通常不會(huì)想要一個(gè)字節(jié)值被返回。即使這個(gè)字符串只有拉丁字母,如果 &"hello"[0] 是返回字節(jié)值的有效代碼,它也會(huì)返回 104 而不是 h。

字節(jié)、標(biāo)量值、字形簇

比如這個(gè)用梵文書(shū)寫(xiě)的印度語(yǔ)單詞 “??????”,最終它儲(chǔ)存在 vector 中的 u8 值看起來(lái)像這樣:

[224, 164, 168, 224, 164, 174, 224, 164, 184, 224, 165, 141, 224, 164, 164,
224, 165, 135]

這里有 18 個(gè)字節(jié),也就是計(jì)算機(jī)最終會(huì)儲(chǔ)存的數(shù)據(jù)。如果從 Unicode 標(biāo)量值的角度理解它們,也就像 Rust 的 char 類型那樣,這些字節(jié)看起來(lái)像這樣:

['?', '?', '?', '?', '?', '?']

這里有六個(gè) char,不過(guò)第四個(gè)和第六個(gè)都不是字母,它們是發(fā)音符號(hào)本身并沒(méi)有任何意義。最后,如果以字形簇的角度理解,就會(huì)得到人們所說(shuō)的構(gòu)成這個(gè)單詞的四個(gè)字母:

["?", "?", "??", "??"]

Rust 提供了多種不同的方式來(lái)解釋計(jì)算機(jī)儲(chǔ)存的原始字符串?dāng)?shù)據(jù),這樣程序就可以選擇它需要的表現(xiàn)方式,而無(wú)所謂是何種人類語(yǔ)言。

        最后一個(gè) Rust 不允許使用索引獲取 String 字符的原因是,索引操作預(yù)期總是需要常數(shù)時(shí)間(O(1))。但是對(duì)于 String 不可能保證這樣的性能,因?yàn)?Rust 必須從開(kāi)頭到索引位置遍歷來(lái)確定有多少有效的字符。

字符串切割slice

索引字符串通常是一個(gè)壞點(diǎn)子,因?yàn)樽址饕龖?yīng)該返回的類型是不明確的:字節(jié)值、字符、字形簇或者字符串 slice。因此,如果你真的希望使用索引創(chuàng)建字符串 slice 時(shí),Rust 會(huì)要求你更明確一些。為了更明確索引并表明你需要一個(gè)字符串 slice,相比使用 [] 和單個(gè)值的索引,可以使用 [] 和一個(gè) range 來(lái)創(chuàng)建含特定字節(jié)的字符串 slice:

let hello = "Здравствуйте";

let s = &hello[0..4];

這里,s 會(huì)是一個(gè) &str,它包含字符串的頭四個(gè)字節(jié)。早些時(shí)候,我們提到了這些字母都是兩個(gè)字節(jié)長(zhǎng)的,所以這意味著 s 將會(huì)是 “Зд”。

如果獲取 &hello[0..1] 會(huì)發(fā)生什么呢?答案是:Rust 在運(yùn)行時(shí)會(huì) panic,就跟訪問(wèn) vector 中的無(wú)效索引時(shí)一樣。你應(yīng)該小心謹(jǐn)慎地使用這個(gè)操作,因?yàn)檫@么做可能會(huì)使你的程序崩潰。

遍歷string

操作字符串每一部分的最好的方法是明確表示需要字符還是字節(jié)。對(duì)于單獨(dú)的 Unicode 標(biāo)量值使用 chars 方法。對(duì) “Зд” 調(diào)用 chars 方法會(huì)將其分開(kāi)并返回兩個(gè) char 類型的值,接著就可以遍歷其結(jié)果來(lái)訪問(wèn)每一個(gè)元素了:

for c in "Зд".chars() {
    println!("{c}");
}

另外 bytes 方法返回每一個(gè)原始字節(jié),這可能會(huì)適合你的使用場(chǎng)景:

for b in "Зд".bytes() {
    println!("");
}

不過(guò)請(qǐng)記住有效的 Unicode 標(biāo)量值可能會(huì)由不止一個(gè)字節(jié)組成。

字符串不簡(jiǎn)單

總而言之,字符串還是很復(fù)雜的。不同的語(yǔ)言選擇了不同的向程序員展示其復(fù)雜性的方式。Rust 選擇了以準(zhǔn)確的方式處理 String 數(shù)據(jù)作為所有 Rust 程序的默認(rèn)行為,這意味著程序員們必須更多的思考如何預(yù)先處理 UTF-8 數(shù)據(jù)。這種權(quán)衡取舍相比其他語(yǔ)言更多的暴露出了字符串的復(fù)雜性,不過(guò)也使你在開(kāi)發(fā)周期后期免于處理涉及非 ASCII 字符的錯(cuò)誤。

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

相關(guān)文章

  • Rust的泛型、Traits與生命周期用法及說(shuō)明

    Rust的泛型、Traits與生命周期用法及說(shuō)明

    本文通過(guò)一個(gè)尋找列表中最大值的示例,展示了如何從重復(fù)代碼中提取函數(shù),再利用泛型實(shí)現(xiàn)代碼復(fù)用,主要步驟包括:識(shí)別重復(fù)邏輯;抽象提??;泛型應(yīng)用;進(jìn)一步擴(kuò)展,通過(guò)不斷抽象和泛化,我們不僅能減少代碼重復(fù),還能寫(xiě)出更通用、健壯和可維護(hù)的代碼
    2025-02-02
  • Rust for循環(huán)語(yǔ)法糖背后的API場(chǎng)景分析

    Rust for循環(huán)語(yǔ)法糖背后的API場(chǎng)景分析

    for語(yǔ)句是一種能確定循環(huán)次數(shù)的循環(huán),for 語(yǔ)句用于執(zhí)行代碼塊指定的次數(shù),今天通過(guò)本文給大家介紹Rust for循環(huán)語(yǔ)法糖背后的API場(chǎng)景分析,感興趣的朋友跟隨小編一起看看吧
    2022-11-11
  • Rust中向量的學(xué)習(xí)筆記

    Rust中向量的學(xué)習(xí)筆記

    在Rust語(yǔ)言中,向量是一種動(dòng)態(tài)數(shù)組類型,可以存儲(chǔ)相同類型的元素,并且可以在運(yùn)行時(shí)改變大小,本文就來(lái)介紹一下Rust中向量,感興趣的可以了解一下
    2024-03-03
  • 一文學(xué)會(huì)Rust語(yǔ)言如何操作JSON

    一文學(xué)會(huì)Rust語(yǔ)言如何操作JSON

    JSON在Web開(kāi)發(fā)中被廣泛應(yīng)用于數(shù)據(jù)交換,本文主要介紹了Rust語(yǔ)言操作JSON,包括序列化、反序列化、JSON創(chuàng)建等多個(gè)方面,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • Rust中的引用與借用舉例詳解

    Rust中的引用與借用舉例詳解

    這篇文章主要給大家介紹了關(guān)于Rust中引用與借用的相關(guān)資料,rust中借用和引用的附帶功效都一樣,就是都有生命周期,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Rust具有一定的參考價(jià)值,需要的朋友可以參考下
    2023-11-11
  • Rust日期與時(shí)間的操作方法

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

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

    Rust文件 launch.json作用大全

    launch.json 是 Visual Studio Code(VSCode)中的一個(gè)配置文件,主要用于配置調(diào)試器,本文給大家介紹Rust文件 launch.json 有什么用,感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • 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文件讀寫(xiě)的實(shí)現(xiàn)示例

    rust文件讀寫(xiě)的實(shí)現(xiàn)示例

    Rust語(yǔ)言提供了強(qiáng)大的文件讀寫(xiě)庫(kù),使得開(kāi)發(fā)者可以更加方便地進(jìn)行文件操作,并且其安全性可以有效避免文件操作中可能出現(xiàn)的風(fēng)險(xiǎn),本文就來(lái)詳細(xì)的介紹了rust文件讀寫(xiě)的實(shí)現(xiàn)示例,感興趣的可以了解一下
    2023-12-12
  • Rust捕獲全局panic并記錄進(jìn)程退出日志的方法

    Rust捕獲全局panic并記錄進(jìn)程退出日志的方法

    本文提供了捕獲全局panic并記錄進(jìn)程退出日志的方法,首先使用 panic::set_hook 注冊(cè)異常處理及panic 觸發(fā)異常,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-04-04

最新評(píng)論

鹿泉市| 乌兰察布市| 伊金霍洛旗| 陕西省| 遵义市| 星子县| 巫溪县| 寻甸| 赤城县| 饶平县| 成都市| 郓城县| 潼南县| 靖边县| 东乌| 维西| 邵东县| 正阳县| 运城市| 平凉市| 祁阳县| 万载县| 西丰县| 安龙县| 新郑市| 贵州省| 攀枝花市| 肥城市| 镇沅| 桐乡市| 屯门区| 老河口市| 繁峙县| 罗山县| 石渠县| 勃利县| 施甸县| 广西| 肃宁县| 齐河县| 德庆县|