Logo

Rust容器

在 Rust 中,Vec 是动态数组,用于存储同类型元素的集合,能够自动调整大小。以下是 Vec 的详细用法,包含常见操作和代码示例:


一、创建 Vec

1. 创建空 Vec

let mut vec: Vec<i32> = Vec::new(); // 空 Vec,需指定类型
let mut vec = Vec::<i32>::new();    // 另一种写法

2. 使用宏 vec! 初始化

let vec = vec![1, 2, 3]; // 类型自动推断为 Vec<i32>
let names = vec!["Alice", "Bob"];

3. 指定容量(优化性能)

let mut vec = Vec::with_capacity(10); // 预分配容量为 10

二、添加元素

1. 末尾添加元素:push

let mut vec = vec![1, 2];
vec.push(3); // vec: [1, 2, 3]

2. 插入元素到指定位置:insert

vec.insert(1, 5); // 在索引 1 处插入 5 → [1, 5, 2, 3]

三、访问元素

1. 通过索引:直接访问(可能 panic)

let first = vec[0]; // 1,索引越界会导致 panic

2. 安全访问:get 返回 Option<T>

match vec.get(2) {
    Some(x) => println!("元素是 {}", x),
    None => println!("索引越界"),
}

3. 访问最后一个元素:.last()

let last = vec.last(); // Some(&3)

四、删除元素

1. 移除末尾元素:pop

let last = vec.pop(); // 返回 Option<T>,例如 Some(3)

2. 移除指定位置元素:remove

let removed = vec.remove(1); // 移除索引 1 处的元素 → 5

3. 清空 Vecclear

vec.clear(); // 清空所有元素,容量不变

五、遍历元素

1. 不可变遍历

for num in &vec {
    println!("{}", num); // 通过引用遍历,不转移所有权
}

2. 可变遍历

for num in &mut vec {
    *num += 1; // 修改元素值
}

3. 转移所有权的遍历

for num in vec {
    println!("{}", num); // 转移所有权,遍历后 vec 不可用
}

六、常用方法

1. 获取长度和容量

let len = vec.len();      // 当前元素个数
let cap = vec.capacity(); // 预分配的内存容量

2. 判断是否为空

if vec.is_empty() {
    println!("Vec 是空的");
}

3. 保留指定容量:reserve

vec.reserve(20); // 确保容量至少为 20

4. 缩减容量:shrink_to_fit

vec.shrink_to_fit(); // 容量缩减至与长度一致

七、切片(Slice)

1. 转换为不可变切片

let slice: &[i32] = &vec[..]; // 获取全部元素的切片
let partial = &vec[1..3];      // 获取索引 1 到 2 的切片

2. 转换为可变切片

let slice_mut: &mut [i32] = &mut vec[..];
slice_mut[0] = 100; // 修改原 Vec 的值

八、转换操作

1. 从数组创建 Vec

let arr = [1, 2, 3];
let vec = arr.to_vec(); // Vec<i32>

2. 从迭代器创建 Vec

let vec: Vec<_> = (1..5).collect(); // [1, 2, 3, 4]

3. 合并两个 Vecappend

let mut vec1 = vec![1, 2];
let mut vec2 = vec![3, 4];
vec1.append(&mut vec2); // vec1: [1, 2, 3, 4], vec2 为空

4.筛选计数

fn count_iterator(map: &HashMap<String, Progress>, value: Progress) -> usize {
    map.values()
        .filter(|&v| *v == value) // 筛选符合条件的元素
        .count()                 // 统计数量
}

九、内存与所有权

所有权规则Vec 拥有其元素,当 Vec 离开作用域时,所有元素会被自动释放。 • 元素所有权:如果元素是 String 或另一个 Vec,它们的资源也会被释放。


十、示例代码

fn main() {
    // 1. 创建 Vec
    let mut numbers = vec![10, 20, 30];
    
    // 2. 添加元素
    numbers.push(40);
    numbers.insert(1, 15); // [10, 15, 20, 30, 40]
    
    // 3. 访问元素
    println!("第三个元素: {}", numbers[2]); // 20
    
    // 4. 删除元素
    numbers.remove(3); // 移除 30 → [10, 15, 20, 40]
    
    // 5. 遍历修改
    for num in &mut numbers {
        *num *= 2;
    } // numbers: [20, 30, 40, 80]
    
    // 6. 转换为切片
    let slice = &numbers[1..3]; // [30, 40]
    
    // 7. 合并 Vec
    let mut others = vec![100, 200];
    numbers.append(&mut others); // numbers: [20, 30, 40, 80, 100, 200]
}

十一、常见问题

  1. 索引越界:直接通过索引访问(如 vec[100])会导致 panic,建议用 get 方法。
  2. 迭代中修改:避免在 for in 循环中直接修改 Vec,可能导致未定义行为。
  3. 容量与性能:频繁插入元素时,预分配容量(with_capacity)可减少内存重分配次数。

通过掌握这些操作,你可以高效地使用 Vec 处理动态集合数据。

© 2025 All rights reservedBuilt with Flowershow Cloud

Built with LogoFlowershow Cloud