1. 切片的核心概念与内存模型
1.1 什么是切片?
切片是对集合中一段连续元素的引用,不获取所有权。Rust的切片是零成本抽象,在运行时表现为一个胖指针(fat pointer),包含:
- 指向数据的指针
- 切片的长度(元素数量)
let arr = [1, 2, 3, 4, 5];
let slice = &arr[1..4]; // 类型为 &[i32]
1.2 内存布局
切片引用在内存中的表示(64位系统):
+--------+--------+
| 指针(8) | 长度(8) |
+--------+--------+
示例数组和切片的内存关系:
数组: [1, 2, 3, 4, 5]
切片 &arr[1..4] 指向:
+---+---+---+
| 2 | 3 | 4 |
+---+---+---+
2. 字符串切片(&str)的特殊性
2.1 UTF-8编码约束
字符串切片必须位于有效的UTF-8字符边界:
let s = "你好,世界";
let ok_slice = &s[0..3]; // "你"(中文字符占3字节)
// let bad_slice = &s[0..2]; // panic! 不是字符边界
2.2 字符串字面值的本质
let s = "hello"; // s的类型是 &'static str
等价于:
static LITERAL: &'static [u8] = b"hello";
let s: &'static str = unsafe { std::str::from_utf8_unchecked(LITERAL) };
3. 切片的创建与操作
3.1 创建语法
语法 | 范围 | 示例 |
---|---|---|
&coll[..] |
全部元素 | &arr[..] |
&coll[a..] |
a到结尾 | &arr[2..] |
&coll[..b] |
开头到b(不含) | &arr[..4] |
&coll[a..b] |
a到b(不含) | &arr[1..4] |
&coll[a..=b] |
a到b(含) | &arr[1..=3] |
3.2 常用操作
let arr = [1, 2, 3, 4, 5];
let slice = &arr[1..4];
// 获取长度
assert_eq!(slice.len(), 3);
// 检查是否为空
assert!(!slice.is_empty());
// 访问元素
assert_eq!(slice[0], 2); // 越界会panic
// 安全访问
assert_eq!(slice.get(3), None); // 返回Option
// 切片的切片
let sub_slice = &slice[1..];
assert_eq!(sub_slice, &[3, 4]);
4. 切片与迭代器
4.1 切片迭代
let nums = [1, 2, 3, 4, 5];
let slice = &nums[1..4];
// 不可变迭代
for num in slice.iter() {
println!("{}", num);
}
// 可变迭代(需原数据可变)
let mut nums = [1, 2, 3, 4, 5];
let slice = &mut nums[1..4];
for n