Rust 中的弦

https://dev.to/samyak112/strings-in-rust-4elm

今天我們將了解 Rust 中的字符串,包括學習 String 和&str,讓我們開始理解每個部分,並嘗試澄清我在閱讀相關內容時遇到的一些疑惑。

&str –

&str 是一個不可變的 UTF-8 編碼字符串切片。由於&str 是不可變的,您無法修改其內容。它是對現有字符串位置的借用引用,並且並非擁有該數據。

String –

String 是一個可增長的、堆分配的字符串。它是可擁有和可變的,允許對其內容進行動態修改。

它是由 Rust 標準庫提供的一種類型,並不像 str 那樣是一種原始類型。它是一個堆分配的、UTF-8 編碼的字符串,可以在運行時動態調整大小。

這是如何創建可變字符串的方式 –
fn main() {
let test = “hello”.to_string();
println!(“{test}”);
}

疑問

這只是對兩者的簡要概述,我在兩者的工作方式上遇到了一些問題,

在&str 中,它默認如何成為現有字符串的借用引用?如果我剛建立一個變數像這樣 let test = “hello”; ,這怎麼成為現有字符串的借用引用?我的意思是我剛剛創建了這個對象對吧?

在可變字符串中,為什麼需要使用.to_string()呢?這不已經是一個字符串了嗎?

為了回答並理解這些問題背後的原因,我們必須首先了解 Rust 中的字符串文字。

字符串文字

字符串文字是直接在您的源代碼中定義的字符序列,如”hello”。它們是不可變的並且嵌入在程序的二進制中,特別是在只讀的部分。

因此,當您創建一個變量像 let greeting = “hello world”;並運行程序時,字符串文字”hello world”被保存在編譯時的二進制中。這意味著一旦編譯您的程序,字符串文字”hello world”已經被放置在編譯二進制檔的只讀部分中。這個過程與聲明可能引用它的任何變量無關。

當代碼實際運行時(已經在“hello world”字符串文字存儲的情況下),greeting 在運行時被初始化為一個借用引用(&’static str),指向只讀部分中存儲的字符串文字。這意味著即使剛剛創建了 greeting 變量,它也立即成為對先前存在的字符串的借用引用,因為字符串在編譯時已經存儲,且因為默認的字符串是不可變的,所以沒有必要對它進行複製,因此直接引用二進製存儲。

這也解釋了為什麼我們需要使用.to_string()來創建可變字符串,因為默認情況下,字符串文字是存儲在只讀二進制中的,所以為了創建一個可以修改的字符串,我們使用.to_string(),這將創建堆上分配的原始字符串文字的副本,這意味著它在運行時可以根據需要改變大小(擴展或縮小)。

基於這個解釋,我試圖將 Rust 中的字符串文字看作是字符串數據的基本形式,具體取決於您的使用方式,它可能保持不變的 str,也可能“轉換”為可變的 String。

在評論中分享一些使用&str 比可變字符串更有利的情況,我的意思是,我知道如果我使用&str,它只是引用某些其他存儲而不是創建一個副本,但除此之外,還有其他使用&str 的好處嗎?

現在,讓我們討論字符串文字如何轉換為&str 或 String。

轉換

不可變&str

當您在 Rust 代碼中直接使用字符串文字時,例如 let greeting = “Hello, world!”;,greeting 是一個不可變的 &’static str。

這意味著它是一個具有’static 壽命的字符串切片的借用引用,指向程序二進制的只讀部分中的數據。

這種形式對於只讀操作、在不擁有的情況下傳遞字符串數據以及字符串數據不需要修改的用例非常有效。

可變 String

如果您需要一個可變、可增長版本的字符串數據,可以通過使用.to_string()或 String::from()等方法將字符串文字轉換為 String。

例如,let mut greeting = “Hello, world!”.to_string();創建了一個 String 對象從字符串文字。

String 類型是堆分配的、可增長的和可變的。它允许您修改字符串數據,例如追加文本或更改字符。

將字符串文字轉換為 String 涉及將數據從二進制的只讀部分復制到堆上分配的內存。此操作使您對複製的數據擁有全權並控制,包括修改它的能力。

在後台工作

內存分配:原始字符串文字保持不變,存儲在程序的二進制的只讀段中。String 對象涉及在堆上另外分配內存,其中包含從字符串文字復制的內容。

數據復制:這意味著您現在擁有“Hello, world!”字符串數據的兩個副本:一個嵌入在程序的二進制(原始字符串文字)的只讀內存中,另一個存儲在堆內存中作為一個 String 對象(.to_string()的結果)。

可變性和所有權:這兩者之間的關鍵區別在於對字符串文字的引用&’static str 是不可變的並且有靜態壽命,而 String 對象是可變的、可增長的並由 greeting 變量擁有。這種所有權帶來了 Rust 內存安全的保證,確保當 greeting 超出范圍或不再需要時,堆內存將被正確地釋放。

所以現在,我們了解了可變的 hello world 的所有權是由 greeting 變量擁有的,那麼誰擁有字符串文字的所有權呢?

在 Rust 中,字符串文字沒有“所有者”的傳統意義上對堆分配內存的用法。相反,它們被烘烤到程序的二進制中,並在程序的執行上下文中加載到內存中。它們是不可變的並且在程序中的任何地方都是全局訪問的。

這些都是我在理解 Rust 中的字符串時感興趣的一些點,如果我錯過了某些與字符串相關的東西或者我傳達了一些概念,請讓我知道。

感謝您閱讀到這裡 😁。

via DEV Community

March 12, 2024 at 01:33PM

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *