理解 Rust 中的字符串:`String` 与字符串字面量 (`&str`)

发布: (2026年2月21日 GMT+8 16:07)
4 分钟阅读
原文: Dev.to

Source: Dev.to

字符串字面量 (&str)

  • 固定的、不可变的 UTF‑8 字节序列,在编译时已知。
  • 直接存放在程序的二进制文件中(只读静态内存)。
  • 零成本使用:编译器把字节嵌入代码,运行时只在栈或寄存器中创建一个 胖指针(指针 + 长度)。
  • 生命周期为 'static —— 整个程序运行期间都有效。
let s: &str = "hello";
  • "hello" 被放置在可执行文件的只读数据段。
  • 没有堆分配、没有系统调用——只有指针和长度。

String

  • 可增长、拥有所有权、可变的 UTF‑8 缓冲区,分配在堆上。
  • 可以修改(例如 push_strpush)。
  • 在栈上保存三部分:指向堆缓冲区的指针、长度和容量。
let s = String::from("hello");
  • 在堆上分配内存,将 "hello" 复制进去,并自动管理缓冲区的生命周期(超出作用域时释放)。

对比

特性&str(字符串字面量)String
可变性不可变可变
内存位置只读二进制段(静态)堆(可增长)
创建方式"hello"&"hello"String::from("hello")
性能访问更快,无分配由于堆分配而较慢
典型使用场景静态文本,函数参数动态字符串构建

存储细节

类型存储位置细节
&str只读二进制段指针 + 长度临时位于栈上;字节已嵌入可执行文件中。
String可增长缓冲区;指针、长度和容量存储在栈上。

分配与运行时开销

类型是否堆分配?相对速度
&'static str❌ 无非常快
String✅ 是较慢(堆操作)

字符串字面量并不是“分配更快”;它们只是根本避免了运行时的堆分配。

示例:使用字符串字面量

let s = "hello"; // `s` 是一个 `&'static str`
  • 字节 "hello" 已经是二进制的一部分。
  • 在运行时,Rust 只在栈上创建一个小的引用(指针 + 长度)。

示例:创建 String

let s = String::from("hello");
  • 在堆上分配内存,复制字节,并将元数据存储在栈上。
  • s 超出作用域时,缓冲区会自动释放。

总结

  • &str – 不可变,编译时已知,存储在静态只读内存中,引用时零成本。
  • String – 可变,堆分配,可增长或收缩,带有分配开销。

了解这些差异有助于在特定情境下选择合适的类型:对静态文本和函数参数使用 &str,在需要可变、动态构建的字符串时使用 String

0 浏览
Back to Blog

相关文章

阅读更多 »

Steel Bank Common Lisp

关于 Steel Bank Common Lisp(SBCL),它是一款高性能的 Common Lisp 编译器。它是开源/自由软件,采用宽松的许可证。除此之外,...

Rust 调试调查 2026

概述:我们正在发起一项 Rust 调试调查。调试 Rust 代码常被认为是 Rust 开发者面临的最大挑战之一。虽然它是 pos...