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

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

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

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

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

字符串是什么

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

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

創(chuàng)建字符串

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

let mut s = String::new();

這新建了一個叫做 s 的空的字符串,接著我們可以向其中裝載數(shù)據(jù)。通常字符串會有初始數(shù)據(jù),因為我們希望一開始就有這個字符串。為此,可以使用 to_string 方法,它能用于任何實現(xiàn)了 Display trait 的類型,比如字符串字面值。

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

因為字符串應用廣泛,這里有很多不同的用于字符串的通用 API 可供選擇。其中一些可能看起來多余,不過都有其用武之地!在這個例子中,String::from 和 .to_string 最終做了完全相同的工作,所以如何選擇就是代碼風格與可讀性的問題了。

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 的大小可以增加,其內容也可以改變,就像可以放入更多數(shù)據(jù)來改變 Vec 的內容一樣。另外,可以方便的使用 + 運算符或 format! 宏來拼接 String 值。

使用push_str和push附加字符串

可以通過 push_str 方法來附加字符串 slice,從而使 String 變長:

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

執(zhí)行這兩行代碼之后,s 將會包含 foobar。push_str 方法采用字符串 slice,因為我們并不需要獲取參數(shù)的所有權。

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

push 方法被定義為獲取一個單獨的字符作為參數(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 被移動了,不能繼續(xù)使用

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

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

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

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

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

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

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

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

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

索引字符串

在很多語言中,通過索引來引用字符串中的單獨字符是有效且常見的操作。然而在 Rust 中,如果你嘗試使用索引語法訪問 String 的一部分,會出現(xiàn)一個錯誤。

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

錯誤和提示說明了全部問題:Rust 的字符串不支持索引。那么接下來的問題是,為什么不支持呢?為了回答這個問題,我們必須先聊一聊 Rust 是如何在內存中儲存字符串的。

內部表示

String 是一個 Vec<u8> 的封裝。

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

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

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

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

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

比如這個用梵文書寫的印度語單詞 “??????”,最終它儲存在 vector 中的 u8 值看起來像這樣:

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

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

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

這里有六個 char,不過第四個和第六個都不是字母,它們是發(fā)音符號本身并沒有任何意義。最后,如果以字形簇的角度理解,就會得到人們所說的構成這個單詞的四個字母:

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

Rust 提供了多種不同的方式來解釋計算機儲存的原始字符串數(shù)據(jù),這樣程序就可以選擇它需要的表現(xiàn)方式,而無所謂是何種人類語言。

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

字符串切割slice

索引字符串通常是一個壞點子,因為字符串索引應該返回的類型是不明確的:字節(jié)值、字符、字形簇或者字符串 slice。因此,如果你真的希望使用索引創(chuàng)建字符串 slice 時,Rust 會要求你更明確一些。為了更明確索引并表明你需要一個字符串 slice,相比使用 [] 和單個值的索引,可以使用 [] 和一個 range 來創(chuàng)建含特定字節(jié)的字符串 slice:

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

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

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

如果獲取 &hello[0..1] 會發(fā)生什么呢?答案是:Rust 在運行時會 panic,就跟訪問 vector 中的無效索引時一樣。你應該小心謹慎地使用這個操作,因為這么做可能會使你的程序崩潰。

遍歷string

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

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

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

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

不過請記住有效的 Unicode 標量值可能會由不止一個字節(jié)組成。

字符串不簡單

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

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

相關文章

  • Rust 模式匹配示例詳解

    Rust 模式匹配示例詳解

    這篇文章主要為大家介紹了Rust 模式匹配示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • 使用Rust實現(xiàn)日志記錄功能

    使用Rust實現(xiàn)日志記錄功能

    這篇文章主要為大家詳細介紹了使用Rust實現(xiàn)日志記錄功能的相關知識,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的可以參考一下
    2024-04-04
  • Rust中的模塊系統(tǒng)之控制作用域與私有性詳解

    Rust中的模塊系統(tǒng)之控制作用域與私有性詳解

    這篇文章總結了Rust模塊系統(tǒng)的基本規(guī)則,包括如何聲明模塊、路徑訪問、私有性與公開性,以及如何使用`use`關鍵字簡化路徑引用,通過一個餐廳系統(tǒng)示例,展示了如何利用模塊劃分功能,并介紹了如何在其他模塊或二進制crate中使用這些模塊
    2025-02-02
  • Rust錯誤處理之`foo(...)?`的用法與錯誤類型轉換小結

    Rust錯誤處理之`foo(...)?`的用法與錯誤類型轉換小結

    foo(...)?語法糖為Rust的錯誤處理提供了極大的便利,通過結合map_err方法和From?trait的實現(xiàn),你可以輕松地處理不同類型的錯誤,并保持代碼的簡潔性和可讀性,這篇文章主要介紹了Rust錯誤處理:`foo(...)?`的用法與錯誤類型轉換,需要的朋友可以參考下
    2024-05-05
  • Rust中into和from用法及區(qū)別介紹

    Rust中into和from用法及區(qū)別介紹

    這篇文章主要介紹了Rust中的?into和from使用及區(qū)別介紹,into和from是Rust語言中兩個用于類型轉換的函數(shù),它們分別屬于Into和From這兩個trait,本文通過實例代碼詳細講解,需要的朋友可以參考下
    2023-04-04
  • Rust實現(xiàn)構建器模式和如何使用Bon庫中的構建器

    Rust實現(xiàn)構建器模式和如何使用Bon庫中的構建器

    這篇文章主要介紹了Rust實現(xiàn)構建器模式和如何使用Bon庫中的構建器,本文給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • Rust讀取配置文件的實現(xiàn)步驟

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

    任何項目都離不開對于配置文件的讀取和解析,rust項目也一樣,本文主要介紹了Rust讀取配置文件的實現(xiàn)步驟,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • Rust開發(fā)環(huán)境搭建到運行第一個程序HelloRust的圖文教程

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

    本文主要介紹了Rust開發(fā)環(huán)境搭建到運行第一個程序HelloRust的圖文教程,文中通過圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-12-12
  • Rust中的&和ref使用解讀

    Rust中的&和ref使用解讀

    在Rust中,`&`和`ref`都可以用來定義指針,但它們的使用位置不同,`&`通常放在等號右邊,而`ref`放在左邊,`&`主要用于函數(shù)參數(shù)和模式匹配中,而`ref`主要用于模式匹配中,Rust通過`&`和`ref`提供了靈活的指針操作,使得代碼更加安全和高效
    2025-02-02
  • rust多個mod文件引用和文件夾mod使用注意事項小結

    rust多個mod文件引用和文件夾mod使用注意事項小結

    在 Rust 項目中,可以使用 mod 關鍵字將一個文件夾或一個 rs 文件作為一個模塊引入到當前文件中,本文給大家介紹rust多個mod文件引用和文件夾mod使用注意事項小結,感興趣的朋友跟隨小編一起看看吧
    2024-03-03

最新評論