3.5 切片类型

切片(slice)是 Rust 中一种重要的引用类型,它允许你安全地引用集合中连续的一段数据,而无需拥有或复制该数据。切片不包含所有权,仅指向某个已存在的数组、向量或字符串的一部分。

字符串切片 &str

在 Rust 中,String 是一个堆分配的、可变的、拥有所有权的字符串类型,而 &str 是一个字符串切片,通常以字面量形式出现或从 String 中借用而来。

例如:

let s = String::from("hello world");
let hello = &s[0..5];   // 类型为 &str
let world = &s[6..11];  // 类型为 &str

这里,helloworld 并不拥有数据,它们只是指向 s 中某一段字节的引用。因为是引用,所以受借用规则约束:只要这些切片存在,s 就不能被修改或移动。

字符串字面量本身就是 &str 类型:

let literal: &str = "hello"; // 存储在程序二进制文件的只读内存中

由于 &str 不涉及所有权转移,它常被用作函数参数,以接受各种字符串形式:

fn print_str(s: &str) {
    println!("{}", s);
}

let s = String::from("hello");
print_str(&s);        // 传入 &String,自动转为 &str
print_str("world");   // 直接传入字符串字面量

这种设计使函数更通用,避免不必要的内存分配。

其他切片类型

除了字符串切片,Rust 还支持对数组和 Vec<T> 的切片,类型为 &[T]

例如:

let a = [1, 2, 3, 4, 5];
let slice = &a[1..3]; // 类型为 &[i32],包含 [2, 3]

同样适用于 Vec

let v = vec![10, 20, 30, 40];
let part = &v[1..3]; // &[i32]

切片类型 &[T] 包含两个部分:指向数据的指针和长度。因此,它可以在运行时表示任意长度的连续元素序列,而数组类型 [T; N] 的长度是编译期固定的。

切片的安全性

Rust 在创建切片时会进行边界检查。如果索引越界,程序会在运行时 panic,从而防止缓冲区溢出等安全问题。

例如:

let s = String::from("hello");
let bad = &s[10..]; // panic! 越界访问

这种检查确保了切片始终指向有效内存。

小结

切片是 Rust 中高效、安全处理连续数据序列的核心工具。&str 用于字符串,&[T] 用于任意类型的序列,它们都以引用形式存在,不拥有数据,因此遵循借用规则。通过使用切片而非完整所有权类型,你可以编写更灵活、零拷贝且内存安全的代码。理解切片与 StringVec<T> 等拥有类型的区别,是掌握 Rust 数据处理方式的关键一步。

#Rust 入门教程 分享于 1 周前

内容由 AI 创作和分享,仅供参考