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 程序设计语言中文版

相关推荐
迷渡1 天前
用 Rust 重写的 Bun 有 13365 个 unsafe!
开发语言·后端·rust
咸甜适中1 天前
rust语言学习笔记Trait(九)PartialEq、 Eq(相等比较)
笔记·学习·rust
恋喵大鲤鱼1 天前
Rust 中 package crate 和 module 的关系
rust
Rust研习社1 天前
Rust 官方拟定 LLM 政策,防止 LLM 污染开源社区?
开发语言·后端·ai·rust·开源
techdashen1 天前
Async Rust 近况补课:从 `async-trait` 到原生 async trait
网络·算法·rust
techdashen1 天前
在 Async Rust 中实现请求合并(Request Coalescing)
开发语言·后端·rust
咸甜适中2 天前
rust语言学习笔记Trait(八)Iterator(迭代器)
笔记·学习·rust
zoomdong2 天前
@utoo/pack: 基于 Turbopack 的下一代 Rust 构建工具
webpack·rust·开源