Rust Vec集合
学习Vec · 难度:入门 · +10XP
Rust Vec 集合
Vec<T>(Vector)是 Rust 中最常用的动态数组集合类型。与数组不同,Vec 的大小可以动态增长和收缩,所有元素必须类型相同。Vec 在堆上分配内存,由所有权系统自动管理,当 Vec 离开作用域时,它和它包含的所有元素都会被自动释放——这意味着你不需要手动 free,也无需担心内存泄漏。
创建与初始化 Vec
Rust 提供了多种创建 Vec 的方式。你可以使用 Vec::new() 创建一个空 Vec,也可以使用 vec! 宏在创建时直接初始化元素。如果已知大致容量,可以使用 Vec::with_capacity() 预先分配空间以提升性能。
fn main() {
// 创建空 Vec
let mut numbers: Vec<i32> = Vec::new();
numbers.push(10);
numbers.push(20);
numbers.push(30);
// 使用 vec! 宏创建并初始化
let fruits = vec!["苹果", "香蕉", "橘子", "葡萄"];
// 预分配容量(避免多次重新分配)
let mut scores = Vec::with_capacity(100);
for i in 0..100 {
scores.push(i * 10);
}
// 使用 collect 从迭代器构建
let squares: Vec<i32> = (1..=5).map(|x| x * x).collect();
println!("平方数: {:?}", squares); // [1, 4, 9, 16, 25]
}
常用操作
| 方法 | 功能 | 示例 |
|---|---|---|
push(val) | 在末尾添加元素 | v.push(42); |
pop() | 移除并返回末尾元素(Option) | let last = v.pop(); |
len() | 返回元素个数 | println!("{}", v.len()); |
insert(idx, val) | 在指定位置插入元素 | v.insert(0, 99); |
remove(idx) | 移除指定位置的元素 | let x = v.remove(2); |
get(idx) | 安全索引访问(返回 Option) | v.get(3) |
v[idx] | 直接索引访问(越界会 panic) | let x = v[0]; |
contains(&val) | 检查是否包含某个值 | v.contains(&5) |
sort() | 升序排序 | v.sort(); |
遍历 Vec
fn main() {
let mut numbers = vec![10, 20, 30, 40, 50];
// 不可变迭代(只读)
for n in &numbers {
print!("{} ", n); // 10 20 30 40 50
}
println!();
// 可变迭代(修改元素)
for n in &mut numbers {
*n *= 2; // 每个元素翻倍
}
println!("翻倍后: {:?}", numbers); // [20, 40, 60, 80, 100]
// 带索引的迭代
for (i, val) in numbers.iter().enumerate() {
println!("索引 {}: 值为 {}", i, val);
}
// 消耗性迭代(迭代后 numbers 不再可用)
let sum: i32 = numbers.iter().sum();
// 或者: numbers.into_iter().sum() -- 这会消耗 numbers
}
切片操作与内存管理
Vec 可以通过 &vec[start..end] 创建切片(slice),切片是对 Vec 中连续元素的引用,不拥有数据的所有权。Vec 的 drain() 方法可以批量移除并返回元素,常用在需要取出并处理一段连续数据的场景中。
- 创建 Vec,添加 1-10 这 10 个数字,使用迭代器筛选出所有偶数并收集到新 Vec 中
- 使用
sort()和sort_by()对字符串 Vec 分别按字母序和长度排序 - 实现一个函数接收 Vec,去除其中的重复元素(使用
contains()判断) - 使用切片获取 Vec 的前三个和后三个元素,分别打印
- 测试直接索引访问(
v[100]越界)与v.get(100)的区别,理解 panic 与 Option 的差异