在 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
}
实际应用场景
这些向量操作在实际开发中非常常见:
- 网络编程:创建数据包缓冲区
- 图像处理:存储像素数据
- 数据分析:处理数值序列
- 游戏开发:管理游戏对象列表
- 文件处理:读取和处理字节流
性能考虑
向量在性能方面有很多优化:
- 内存连续性:元素在内存中连续存储,缓存友好
- 动态扩容:自动扩容策略减少重新分配频率
- 零成本抽象:编译后的性能与手写 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 的更多强大功能!
15万+

被折叠的 条评论
为什么被折叠?



