Rust中的String VS str
最近在寫C++,業餘時間在學習Rust,這好像是我第二次學了,第一次學習對有的概念還是很懵逼的,最近寫了C++之後,好多東西理解起來不是那麼吃力了,裡面的概念超級多,好記性不如爛筆頭,還是記錄一下吧。
在Rust的官方文件References and Borrowing [ofollow,noindex">https://doc.rust-lang.org/book/second-edition/ch04-02-references-and-borrowing.html ] 用到了三種不同型別的string變數:String,&String 和 &str
首先看一下str 和 String之間的區別:String是一個可變的、堆上分配的UTF-8的位元組緩衝區。而str是一個不可變的固定長度的字串,如果是從String解引用而來的,則指向堆上,如果是字面值,則指向靜態記憶體。
舉例說明 String 和 &str
let a = "hello world"; let b = "OK"; let mut s = String::from("Hello Rust"); println!("{}", s.capacity());// prints 12 s.push_str("Here I come!"); println!("{}", s.len()); // prints 24 let s = "Hello, Rust!"; println!("{}", s.capacity()); // compile error: no method named `capacity` found for type `&str` println!("{}", s.len()); // prints 12
-
上面的a, b 是&str,不是String,&str更像一個固定的陣列,String像一個可變的陣列。
-
String保留了一個len()和capacity(),但str只有一個len()。
-
&str 是 str的一個的borrowed 型別,可以稱為一個字串切片,一個不可變的string。
關於&String
&String 是String的borrowed型別,這只不過是一個指標型別,可以傳遞而不放棄ownership。事實上,一個&String可以當做是&str。
fn main() { let s = String::from("Hello, Rust!"); foo(&s); } fn foo(s: &str) { println!("{}", s); }
foo()可以使用string slice或者borrowed String型別。
如果我們想修改字串的內容,只需要傳遞一個可變引用就行了。
fn main() { let mut s = String::from("Hello, Rust!"); foo(&mut s); } fn foo(s: &mut String) { s.push_str("appending foo.."); println!("{}", s); }
相互轉換
&str => String
let c = a.to_string(); let d = String::from(b); let d = a.to_owned();
String => &str
let e = &String::from("Hello Rust"); // 或使用as_str() let e_tmp = String::from("Hello Rust"); let e = e_tmp.as_str(); // 不能直接這樣使用 // let e = String::from("Hello Rust").as_str();
String + &str => String
String後面接上N個&str
let mut strs = "Hello".to_string(); // let mut strs = String::from("Hello"); strs.push_str(" Rust"); println!("{}", strs);
總結
如果只想要一個字串的只讀檢視,或者&str作為一個函式的引數,那就首選&str。如果想擁有所有權,想修改字串那就用String吧。