在 Rust 中,"hello"
?和?String::from("hello")
?都表示字符串,但它們在內存表示、所有權和可變性上有本質區別:
1.?類型與內存表示
"hello"
?(字符串字面量):類型為?
&str
(字符串切片引用)存儲在程序的只讀內存區(如代碼段或靜態存儲區)
編譯時大小固定,不可變
內存布局:胖指針(指針 + 長度),不包含容量字段
String::from("hello")
:類型為?
String
(堆分配的字符串)數據存儲在堆內存中
內存布局:棧上結構(指針 + 長度 + 容量),指向堆數據
2.?所有權與可變性
特性 | "hello" ?(&str ) | String::from("hello") ?(String ) |
---|---|---|
所有權 | 無所有權(借用) | 擁有所有權 |
可變性 | 永遠不可變 | 可修改(需聲明?mut ) |
生命周期 | 靜態('static )或借用 | 動態(隨變量作用域結束釋放) |
3.?性能特點
"hello"
:零運行時開銷(編譯時分配)
無堆分配,訪問高效
String::from("hello")
:運行時在堆上分配內存
適合動態構建/修改字符串
4.?相互轉換
// &str → String(堆分配復制)
let s: String = "hello".into(); // String → &str(零成本轉換)
let slice: &str = &s;
5.?使用場景
優先使用?
&str
:函數參數傳遞(
fn foo(s: &str)
)讀取靜態字符串(如配置字面量)
使用?
String
:需要修改字符串內容
動態構建字符串(如用戶輸入)
需要所有權的場景(如結構體字段)
示例代碼
fn main() {// 字符串字面量(只讀內存)let static_str: &str = "hello";// static_str.push('!'); // 錯誤:不可變// String 類型(堆分配)let mut heap_string = String::from("hello");heap_string.push('!'); // 允許修改// 轉換示例let from_static: String = static_str.to_string(); // 復制到堆let from_heap: &str = &heap_string; // 借用為切片println!("Static: {}", static_str); // "hello"println!("Heap: {}", heap_string); // "hello!"
}
內存示意圖
靜態存儲區 棧 堆
+----------+ +-----------+ +-------+
| "hello" | <-- | ptr/len | | | <- &str 切片
+----------+ +-----------+ +-------++-----------+ +-------+| ptr | --> | "hello!" | <- String| len=6 | +-------+| capacity=8| +-----------+
總結:
??"hello"
:高效只讀,適合靜態文本
??String::from("hello")
:靈活可變,適合動態操作
根據需求選擇合適的類型可優化性能和內存使用。