首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Rust Vec: 从零开始掌握Vec动态数组

Rust Vec: 从零开始掌握Vec动态数组

作者头像
不吃草的牛德
发布2026-04-23 11:12:32
发布2026-04-23 11:12:32
640
举报
文章被收录于专栏:RustRust

Rust 是一门以内存安全和性能著称的现代编程语言,而 Vec 是 Rust 中最常用的动态数组类型,灵活又高效。无论你是想存储一串数字、字符串,还是管理动态数据,Vec 都是你的好帮手!

想象你需要一个“伸缩自如的口袋”,可以随时装入或取出东西。Rust 的 Vec 就像这样的口袋,它是一个动态数组,能根据需要自动扩展或收缩。本文将通过简单示例,教你如何创建、操作 Vec,并理解 Rust 的内存安全。


Vec 基础概念Vec 是 Rust 提供的动态数组类型,存储在堆内存上,可以动态增长或缩小。与固定长度的数组(如 [i32; 3])不同,Vec 的大小可以随时变化,非常适合处理动态数据。为什么选择 Vec?

  • 灵活性:随时添加或删除元素,不受固定长度限制。
  • 内存安全:Rust 的所有权和借用机制确保 Vec 操作不会导致内存泄漏或非法访问。
  • 高性能:Vec 在堆上高效分配内存,适合各种场景。

所有权与借用Rust 的所有权规则对 Vec 至关重要:

  • Vec 拥有其存储的数据,释放 Vec 时,数据也会被清理。
  • 借用(&Vec 或 &mut Vec)允许安全访问或修改数据,避免意外修改。

可以通过std::vec 文档深入了解。


让我们通过三个简单示例,学习 Vec 的核心操作。代码都可以在 src/main.rs 中运行。

示例 1:创建和初始化 Vec

代码语言:javascript
复制
fn main() {
    // 创建空的 Vec
    let mut numbers: Vec<i32> = Vec::new();
    // 添加元素
    numbers.push(1);
    numbers.push(2);
    numbers.push(3);
    println!("Numbers: {:?}", numbers); // 输出: Numbers: [1, 2, 3]
    // 使用 vec! 宏快速初始化
    let fruits = vec!["apple", "banana", "orange"];
    println!("Fruits: {:?}", fruits); // 输出: Fruits: ["apple", "banana", "orange"]
}

解释:

  • Vec::new() 创建空 Vec,mut 关键字允许修改。
  • push 方法在末尾添加元素,自动扩展内存。
  • vec! 宏是快速初始化的简便方式。
  • Rust 的内存安全确保 push 操作不会溢出,Vec 内部会自动管理内存。

示例 2:操作与迭代

代码语言:javascript
复制
fn main() {
    let mut scores = vec![85, 90, 95];
    // 删除元素
    scores.remove(1); // 删除索引 1 的元素(90)
    println!("After remove: {:?}", scores); // 输出: [85, 95]
    // 迭代 Vec
    for score in &scores {
        println!("Score: {}", score);
    }
    // 可变借用修改元素
    for score in &mut scores {
        *score += 5; // 每个分数加 5
    }
    println!("After increase: {:?}", scores); // 输出: [90, 100]
}

解释:

  • remove 删除指定索引的元素,Rust 确保索引有效,避免越界。
  • &scores 借用 Vec 进行只读迭代,&mut scores 允许修改。
  • Rust 的借用检查器防止数据竞争,确保安全修改。

示例 3:处理用户输入假设我们要存储用户输入的待办事项列表:

代码语言:javascript
复制
use std::io;
fn main() {
    let mut todos: Vec<String> = Vec::new();

    // 模拟用户输入
    println!("Enter a todo item (or 'quit' to exit):");
    loop {
        let mut input = String::new();
        io::stdin().read_line(&mut input).expect("Failed to read input");
        let input = input.trim();

        if input == "quit" {
            break;
        }
        todos.push(input.to_string());
    }

    println!("Your todos: {:?}", todos);
}

解释:

  • 使用 Vec<String> 存储动态输入的字符串。
  • push 将用户输入存入 Vec,Rust 的所有权确保字符串被正确管理。
  • 实际场景中,Vec 适合处理动态列表,如任务管理或数据收集。

常见问题与调试

  1. 索引越界:
    • 错误:index out of bounds: the len is 3 but the index is 3
    • 解决:使用 get 方法代替直接索引,如 scores.get(3) 返回 Option,避免崩溃。
    • 示例:if let Some(score) = scores.get(0) { println!("{}", score); }
  2. 所有权问题:
    • 错误:use of moved value(尝试多次使用 Vec 后被移动)。
    • 解决:使用引用(&scores)或克隆(scores.clone())。
    • 示例:let scores_copy = scores.clone();
  3. 依赖问题:
    • 如果 cargo run 失败,运行 rustup update 或检查网络连接。

总结与扩展恭喜你掌握了 Vec 的基本用法!通过本教程,你学会了创建、操作 Vec,并理解了 Rust 的所有权和借用机制。Vec 是 Rust 编程的基石,广泛用于数据存储和处理。扩展任务:

  • 实现待办事项管理:扩展示例 3,添加删除任务(remove)或标记完成(存储 (String, bool) 的 Vec)。
  • 排序与过滤:尝试用 sort 方法对 Vec<i32> 排序,或用 filter 筛选特定元素。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-09-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Rust火箭工坊 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档