Rust 中的字符串 slice 是什么?

文章目录

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] 的异同,我可以继续为你解释。


参考文献

Rust 程序设计语言中文版

相关推荐
fox_lht1 天前
15.3.改进我们之前的输入、输出项目
开发语言·后端·学习·rust
guyoung1 天前
BoxAgnts 工具系统(6)——多 Provider 适配与 Agent 查询循环
rust·agent·ai编程
星栈1 天前
Rust + Makepad 应用怎么打包发布:Windows、macOS、Linux 全平台交付
前端·rust
MageGojo1 天前
R-Shell开源项目实战解析:用Rust打造命令行SSH工具,支持连接管理、远程执行、SFTP与MCP
运维·rust·开源项目·命令行工具·ssh客户端·mcp
techdashen1 天前
Cargo 1.94 开发周期全解析
开发语言·后端·rust
fox_lht1 天前
15.4.循环和迭代器的性能比较
开发语言·后端·学习·rust
guyoung1 天前
BoxAgnts 工具系统(5)——WASM 工具开发:从 Hello World 到生产部署
rust·agent·ai编程
星栈1 天前
写 Makepad Demo 不难,难的是把它写成项目
前端·rust
咸甜适中1 天前
rust语言学习笔记Trait(十七)Send、Sync(线程间数据所有权)
笔记·学习·rust
javajenius1 天前
Pixi:用 Rust 重写 Conda 体验的包管理工具
开发语言·其他·rust·conda