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

你可能感兴趣的:(Rust,rust,开发语言,后端,字符串)