Rust 中字符串类型区别解析
在 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")
:灵活可变,适合动态操作
根据需求选择合适的类型可优化性能和内存使用。