You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Rust中str类型长度可变,而String类型大小固定?

Rust中&str与String的核心区别及入门细节

核心疑问解答:为什么String可以作为自有类型?

首先纠正一个误解:String本质也是通过栈上固定结构引用堆数据,它本身是固定大小的结构体(64位系统中占24字节),包含三个明确的字段:

  • 指向堆中字符数据的指针
  • 当前字符串的已用字节长度
  • 堆分配的总容量(可用字节数)

正因为String自身的大小是编译期确定的,所以它可以作为自有类型直接存储在栈上,不需要额外的引用。而str是动态大小类型(DST)——它的长度只有运行时才知道,栈无法直接存储不确定大小的数据,因此必须通过&str(胖指针,包含指针和长度两个字段,64位系统占16字节)来间接引用。

入门必备细节梳理

1. 定义与本质

  • &str:字符串切片,是对一段UTF-8字符序列的不可变引用,可指向栈上的字符串字面量(如"hello"),也可指向堆上String的某一部分。它是借用类型,无所有权。
  • String:可增长、可修改的自有字符串类型,数据存储在堆上,拥有堆内存的所有权,支持追加、截断、替换等修改操作。

2. 内存布局对比

  • &str(胖指针):栈上存储两个usize值——字符数据的起始地址,以及数据的字节长度。
  • String:栈上存储三个usize值——堆数据的起始指针、当前已用长度、堆总容量。堆上存储实际的UTF-8字节序列。

3. 常用使用场景

  • 优先用&str的场景:
    • 函数参数:无需修改字符串时,&str可同时接受字符串字面量和String的引用(String可自动解引用为&str),灵活性更高。
    • 引用字符串的部分内容:比如&my_string[1..4]获取子串切片。
    • 只读场景:处理固定配置、日志消息等无需修改的文本。
  • 优先用String的场景:
    • 需要修改字符串内容时:比如my_string.push('!')追加字符、替换子串等操作。
    • 需要拥有字符串所有权时:比如从文件读取文本、动态生成字符串后作为返回值返回。

4. 类型转换

  • String转&str:直接取引用&my_string,或调用my_string.as_str()方法。
  • &str转String:调用"text".to_string(),或使用String::from("text")、"text".into()。
  • 字符串字面量转String:"hello".to_string()或String::from("hello")。

5. 关键注意事项

  • str除了通过&str引用,还可以用Box<str>(装箱字符串),它拥有堆数据的所有权,但Box<str>是智能指针,栈上仅存固定大小的指针。
  • 两者均为UTF-8编码,处理非ASCII字符时要注意:字节长度≠字符数(比如中文每个字符占3字节)。
  • &str默认不可变,若需可变的字符串切片,可使用&mut str,但仅能修改现有字符,无法改变字符串长度。

内容的提问来源于stack exchange,提问作者Dainank

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 04:35:00