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

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

向量:Rust 中的动态数组

向量(Vec)是 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]
}

代码深度解析

创建空向量

/// Create an empty vector
pub fn create_empty() -> Vec<u8> {
    Vec::new()
}

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

创建零初始化缓冲区

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

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

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

斐波那契数列

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

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

测试用例详解

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! 宏

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

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

2. 滑动窗口迭代器

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

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

3. 迭代器适配器

assert!(zeroized.iter().all(|&v| v == 0));

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

向量的更多用法

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

基本操作

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

内存预分配

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

收集迭代器结果

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

斐波那契数列的动态生成

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

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 特性结合使用:

// 使用枚举存储不同类型
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 的更多强大功能!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值