文章目录
- 0.前言
- 1.核心定义
- [2.字符串 slice 的两种常见来源](#2.字符串 slice 的两种常见来源)
- [3.String vs &str](#3.String vs &str)
- 4.示例代码
- 5.切片索引注意事项
- 6.为什么需要两种字符串类型?
- 7.总结
- 参考文献
0.前言
在 Rust 中,字符串 slice (&str)是一个对 UTF-8 编码的字符串数据段的不可变引用。它是 Rust 核心字符串类型之一,用于在不拥有数据所有权的情况下,高效地访问字符串的一部分或全部。
1.核心定义
- 语法 :
&str - 本质 :一个胖指针 (fat pointer),包含两部分:
- 指向底层 UTF-8 字节序列的指针。
- 字符串的长度(单位是字节,不是字符数)。
- 内存位置 :可以指向静态内存 (如字符串字面量)、堆内存 (如
String的某一部分)或栈内存(极少见)。 - 可变性 :不可变,不能修改其指向的内容。
2.字符串 slice 的两种常见来源
| 来源 | 示例 | 说明 |
|---|---|---|
| 字符串字面量 | let s: &str = "Hello, world!"; |
字面量类型是 &'static str,指向可执行文件的只读数据段。 |
从 String 借用 |
let s = String::from("hello"); let slice: &str = &s; |
String 实现了 Deref<Target=str>,因此 &String 可自动转换为 &str。 |
从 String 切片 |
let slice = &s[0..4]; |
获取 String 中某一段字节的视图(注意索引必须是 UTF-8 字符边界)。 |
3.String vs &str
| 特性 | String |
&str |
|---|---|---|
| 所有权 | 拥有数据所有权 | 借用数据(无所有权) |
| 内存位置 | 堆(可动态增长) | 可指向静态内存、堆或栈的一部分 |
| 可变性 | ✅ 可修改(如 push_str) |
❌ 不可变 |
| 内部结构 | Vec<u8>(指针、长度、容量) |
胖指针(指针、长度) |
| 使用场景 | 需要拥有、修改或传递字符串数据时 | 需要只读访问字符串、函数参数等 |
4.示例代码
rust
fn main() {
// 1. 字符串字面量(&'static str)
let hello: &str = "Hello"; // 指向静态内存
// 2. 从 String 借用为 &str
let s = String::from("world");
let world: &str = &s; // 自动解引用强制转换
// 3. 字符串 slice 切片(从 String 中获取一部分)
let slice: &str = &s[0..2]; // "wo"(取前两个字节)
println!("slice: {}", slice);
// 4. 字符串 slice 可以连接,但需要转换为 String
let combined = format!("{} {}", hello, world);
println!("{}", combined); // "Hello world"
}
5.切片索引注意事项
字符串 slice 的索引必须按字节 来,且必须落在 UTF-8 字符的边界上。否则程序会 panic。
rust
let s = "你好";
// let slice = &s[0..1]; // ❌ 运行时 panic!因为 '你' 占 3 个字节,索引 1 在字符中间
let slice = &s[0..3]; // ✅ "你"(三字节)
println!("{}", slice);
若需要按字符操作,应使用 .chars() 方法。
6.为什么需要两种字符串类型?
Rust 通过分离 String(拥有所有权的可变字符串)和 &str(借用的不可变视图),实现了:
- 内存安全 :
&str的借用生命周期被编译器检查,避免悬垂引用。 - 零成本抽象:字符串 slice 不会复制数据,只创建视图。
- 高效的 API 设计 :函数参数用
&str可以同时接受String和&str,无需额外转换。
rust
fn greet(name: &str) {
println!("Hello, {}!", name);
}
fn main() {
let name1 = "Alice"; // &str
let name2 = String::from("Bob"); // String
greet(name1); // ✅ 直接传 &str
greet(&name2); // ✅ 传 &String(自动转为 &str)
}
7.总结
&str是字符串的只读视图,不拥有数据,指向一段 UTF-8 编码的字节。- 字符串字面量的类型是
&'static str。 - 可通过
&String或&s[start..end]获得&str。 - 它作为函数参数非常灵活,是 Rust 字符串处理的首选类型。
- 切片索引需按字节进行,且必须位于字符边界。
如果你希望进一步了解 UTF-8 编码边界和按字符操作的方法,或是 str 类型与 [u8] 的异同,我可以继续为你解释。