Rust 练习册 120:探索向量与斐波那契数列

在 Rust 编程学习中,向量(Vector)是最常用且最重要的数据结构之一。今天我们将通过几个简单的练习来深入了解 Rust 中向量的创建、初始化和使用,同时探索经典的斐波那契数列。

向量:Rust 中的动态数组

向量(Vec)是 Rust 标准库中提供的动态数组类型。与传统数组不同,向量的大小可以在运行时动态变化,这使得它在实际编程中非常有用。

核心实现

rust 复制代码
/// Create an empty vector
pub fn create_empty() -> Vec<u8> {
    Vec::new()
}

/// Create a buffer of `count` zeroes.
///
/// Applications often use buffers when serializing data to send over the network.
pub fn create_buffer(count: usize) -> Vec<u8> {
    vec![0; count]
}

/// Create a vector containing the first five elements of the Fibonacci sequence.
///
/// Fibonacci's sequence is the list of numbers where the next number is a sum of the previous two.
/// Its first five elements are `1, 1, 2, 3, 5`.
pub fn fibonacci() -> Vec<u8> {
    vec![1, 1, 2, 3, 5]
}

代码深度解析

创建空向量

rust 复制代码
/// Create an empty vector
pub fn create_empty() -> Vec<u8> {
    Vec::new()
}

这是创建空向量最基本的方法。Vec::new() 返回一个容量为 0 的空向量。由于我们指定了返回类型为 Vec<u8>,编译器知道这是一个存储 u8 类型元素的向量。

创建零初始化缓冲区

rust 复制代码
/// Create a buffer of `count` zeroes.
pub fn create_buffer(count: usize) -> Vec<u8> {
    vec![0; count]
}

这里我们使用了 vec! 宏的重复语法 [value; count] 来创建包含 count 个 0 的向量。这种语法在需要初始化固定值数组时非常有用,比如:

  • 创建零初始化的缓冲区
  • 初始化具有默认值的数组
  • 创建测试数据

斐波那契数列

rust 复制代码
/// Create a vector containing the first five elements of the Fibonacci sequence.
pub fn fibonacci() -> Vec<u8> {
    vec![1, 1, 2, 3, 5]
}

斐波那契数列是一个经典的数学序列,其中每个数字是前两个数字的和。这里我们直接返回了前五个元素的硬编码值。

测试用例详解

rust 复制代码
use short_fibonacci::*;

#[test]
fn test_empty() {
    assert_eq!(create_empty(), Vec::new());
}

#[test]
fn test_buffer() {
    for n in 0..10 {
        let zeroized = create_buffer(n);
        assert_eq!(zeroized.len(), n);
        assert!(zeroized.iter().all(|&v| v == 0));
    }
}

#[test]
fn test_fibonacci() {
    let fibb = fibonacci();
    assert_eq!(fibb.len(), 5);
    for window in fibb.windows(3) {
        assert_eq!(window[0] + window[1], window[2]);
    }
}

测试用例验证了我们函数的正确性:

  • 空向量创建函数返回真正的空向量
  • 缓冲区创建函数返回指定长度的零向量
  • 斐波那契函数返回正确的序列(通过滑动窗口验证性质)

Rust 特性的体现

1. Vec::new() 与 vec! 宏

rust 复制代码
Vec::new()    // 创建空向量
vec![0; 10]   // 创建包含10个0的向量

Rust 提供了多种创建向量的方式,适应不同场景的需求。

2. 滑动窗口迭代器

rust 复制代码
for window in fibb.windows(3) {
    assert_eq!(window[0] + window[1], window[2]);
}

windows() 方法是向量的一个强大功能,它创建一个滑动窗口迭代器,可以方便地处理连续的元素序列。

3. 迭代器适配器

rust 复制代码
assert!(zeroized.iter().all(|&v| v == 0));

all() 是一个迭代器适配器,它检查所有元素是否满足给定条件。这里我们验证所有元素都是 0。

向量的更多用法

向量在实际应用中有丰富的用法:

基本操作

rust 复制代码
let mut vec = Vec::new();
vec.push(1);           // 添加元素
vec.pop();             // 移除最后一个元素
let third = vec[2];    // 索引访问
let len = vec.len();   // 获取长度

内存预分配

rust 复制代码
let mut vec = Vec::with_capacity(100);  // 预分配容量
vec.reserve(50);                        // 确保至少还有50个元素的空间

收集迭代器结果

rust 复制代码
let vec: Vec<i32> = (1..5).collect();  // 从迭代器创建向量

斐波那契数列的动态生成

虽然我们的练习中使用了硬编码,但在实际应用中,我们可能需要动态生成斐波那契数列:

rust 复制代码
pub fn fibonacci_dynamic(n: usize) -> Vec<u64> {
    if n == 0 {
        return vec![];
    }
    if n == 1 {
        return vec![1];
    }
    
    let mut fib = vec![1, 1];
    for i in 2..n {
        let next = fib[i-1] + fib[i-2];
        fib.push(next);
    }
    fib
}

实际应用场景

这些向量操作在实际开发中非常常见:

  1. 网络编程:创建数据包缓冲区
  2. 图像处理:存储像素数据
  3. 数据分析:处理数值序列
  4. 游戏开发:管理游戏对象列表
  5. 文件处理:读取和处理字节流

性能考虑

向量在性能方面有很多优化:

  1. 内存连续性:元素在内存中连续存储,缓存友好
  2. 动态扩容:自动扩容策略减少重新分配频率
  3. 零成本抽象:编译后的性能与手写 C 代码相当

扩展思考

向量可以与许多其他 Rust 特性结合使用:

rust 复制代码
// 使用枚举存储不同类型
enum Data {
    Int(i32),
    Float(f64),
    Text(String),
}
let mixed_data: Vec<Data> = vec![/* ... */];

// 使用结构体存储复杂数据
struct Point { x: f64, y: f64 }
let points: Vec<Point> = vec![/* ... */];

总结

通过这个简单的练习,我们学习了 Rust 中向量的基本用法:

  • Vec::new() 创建空向量
  • vec! 宏创建并初始化向量
  • 向量的基本属性和方法
  • 迭代器与向量的结合使用
  • 向量在实际应用中的重要性

向量是 Rust 中最基础也是最重要的数据结构之一。掌握好向量的使用,是学好 Rust 的关键一步。

在下一篇文章中,我们将继续探索 Rust 的更多强大功能!

相关推荐
Pocker_Spades_A13 小时前
Python快速入门专业版(五十七)——POST请求与模拟登录:从表单分析到实战(以测试网站为例)
开发语言·python
道清茗13 小时前
【RH294知识点汇总】第 3 章 《 管理变量和事实 》1
开发语言·python
星空椰13 小时前
JavaScript基础:运算符和流程控制
开发语言·javascript·ecmascript
Halo_tjn13 小时前
Java 接口的定义重构学生管理系统
java·开发语言·算法
阿Y加油吧13 小时前
栈的经典应用:从「有效括号」到「寻找两个正序数组的中位数」深度解析
开发语言·python·算法
xiaotao13113 小时前
阶段零:Python 安装与虚拟环境(venv / Conda)
开发语言·人工智能·python·conda
BingoGo13 小时前
Laravel13 + Vue3 的免费可商用 PHP 管理后台 CatchAdmin V5.2.0 发布
后端·php·laravel
dr_yingli13 小时前
fMRI(4-1)统计分析报告生成器说明
开发语言·matlab
m0_7167652314 小时前
数据结构--顺序表的插入、删除、查找详解
c语言·开发语言·数据结构·c++·学习·算法·visual studio
Halo_tjn14 小时前
Java 抽象类 知识点
java·开发语言·算法