Rust中的String与str:主要区别及示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Rust中的String与str:为什么新手会混淆以及如何一劳永逸地搞懂

\n\n

如果你刚开始学习Rust,你肯定遇到过这种情况:编译器报错,你试图将String传递给期望&str的地方,或者反过来。熟悉吗?这是Stack Overflow上最热门的问题之一(成千上万的浏览量!),这并非偶然——这个话题对于理解Rust中的内存管理确实至关重要。

\n\n

在本文中,我们将弄清楚String和&str的区别,何时使用哪种类型,以及如何避免典型错误。开始吧!

\n\n

给赶时间的人的简短回答

\n\n

如果你现在就需要答案——记住要点:

\n\n
    \n
  • String — 是一个拥有所有权、可变、动态的数据类型,存储在堆(heap)上。
  • \n
  • &str — 是一个不可变的字符串切片(slice),它引用属于其他人的数据。最常见的形式是&str。
  • \n
\n\n

现在让我们深入探讨。

\n\n

什么是Rust中的String?

\n\n

String是一种拥有其数据的类型。当你创建一个String时,内存会在堆上分配,并且字符串可以增长、缩小或修改。

\n\n
let mut s = String::from("Привет");\ns.push_str(", мир!");\nprintln!("{}", s); // 输出:Привет, мир!
\n\n

这里s是字符串的所有者。当s离开作用域时,内存会自动释放(感谢RAII——资源获取即初始化)。

\n\n

String的主要特性:

\n
    \n
  • 拥有数据(owning type)
  • \n
  • 可变的(mutable)
  • \n
  • 存储在堆上
  • \n
  • 可以从字符串字面量创建:String::from("текст")
  • \n
  • 支持拼接、插入、删除字符
  • \n
\n\n

什么是Rust中的&str?

\n\n

&str(读作“str切片”或“字符串切片”)是一个引用,指向属于其他人的UTF-8字符序列。&str本身只是一个指向数据的指针和长度。

\n\n
let greeting: &str = "Привет";\nprintln!("{}", greeting);
\n\n

在这个例子中,greeting是对字符串字面量的引用,该字面量直接存储在程序的二进制文件中(在只读内存段中)。greeting不拥有这些数据——它只是指向它们。

\n\n

&str的主要特性:

\n
    \n
  • 不拥有数据(borrowed type)
  • \n
  • 不可变的(immutable)
  • \n
  • 要么存储在二进制文件中(字符串字面量),要么存储在堆上(作为String的切片)
  • \n
  • 轻量级——由两个字段组成:指针 + 长度(在64位系统上为16字节)
  • \n
  • 当不需要修改字符串时,非常适合传递给函数
  • \n
\n\n

String和&str的关键区别(表格)

\n\n

让我们将所有内容汇总到一个清晰的表格中:

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
特性String&str
所有权拥有数据借用数据
可变性是(mut)否
存储位置堆(heap)堆、栈或二进制文件
栈上大小24字节(ptr + len + cap)16字节(ptr + len)
创建方式String::from("...")"..." 或 &s[..]
主要用途当需要修改或拥

博客

书籍推荐