1. 数组基础
定义与初始化
rust
let arr1: [i32; 5] = [1, 2, 3, 4, 5]; // 显式类型
let arr2 = [1, 2, 3, 4, 5]; // 类型推断
let zeros = [0; 10]; // 重复初始化
访问与修改
rust
let mut arr = [1, 2, 3];
let first = arr[0]; // 访问
arr[1] = 20; // 修改(需mut)
2. 数组操作
遍历与切片
rust
// 遍历
for num in &arr { println!("{}", num); }
// 切片
let slice = &arr[1..3]; // 不可变切片
let slice_mut = &mut arr[1..3]; // 可变切片
多维数组
rust
let matrix: [[i32; 3]; 2] = [
[1, 2, 3],
[4, 5, 6]
];
let elem = matrix[1][2]; // 6
3. 向量(Vector)基础
创建向量
rust
// 多种创建方式
let v1: Vec<i32> = Vec::new(); // 空向量
let v2 = vec![1, 2, 3]; // 宏初始化
let v3 = Vec::with_capacity(10); // 预分配容量
let v4 = (0..10).collect::<Vec<_>>(); // 迭代器收集
增删改查
rust
let mut vec = vec![1, 2, 3];
// 添加元素
vec.push(4); // 末尾添加 [1,2,3,4]
vec.insert(1, 99); // 指定位置插入 [1,99,2,3,4]
// 删除元素
vec.pop(); // 移除末尾 → Some(4)
vec.remove(1); // 移除索引1 → [1,2,3]
vec.retain(|&x| x > 2); // 条件保留 → [3]
// 访问元素
let first = vec[0]; // 索引访问(panic越界)
let safe = vec.get(5); // Option<&T> 安全访问
4. 向量高级操作
内存管理
rust
let mut vec = vec![1, 2, 3];
println!("长度: {}, 容量: {}", vec.len(), vec.capacity());
vec.shrink_to_fit(); // 收缩容量匹配长度
vec.reserve(10); // 预分配额外空间
vec.truncate(2); // 截断长度 → [1, 2]
vec.clear(); // 清空向量
批量操作
rust
let mut v1 = vec![1, 2, 3];
let v2 = vec![4, 5, 6];
// 合并向量
v1.extend(v2); // v1变为[1,2,3,4,5,6]
// 切片操作
v1.append(&mut vec![7, 8]); // 追加另一向量
v1.split_off(3); // 分割 → [1,2,3] 和 [4,5,6,7,8]
// 拼接
let combined = [v1, v2].concat(); // 连接多个向量
排序与搜索
rust
let mut vec = vec![3, 1, 4, 1, 5];
vec.sort(); // 升序排序
vec.sort_unstable(); // 更快但不稳定
vec.sort_by(|a, b| b.cmp(a)); // 自定义排序
vec.dedup(); // 移除连续重复项
vec.reverse(); // 反转顺序
let pos = vec.binary_search(&4); // 二分查找(需有序)
let idx = vec.iter().position(|&x| x == 3); // 线性查找
5. 向量迭代器
rust
let vec = vec![1, 2, 3, 4, 5];
// 各种迭代方式
let doubled: Vec<_> = vec.iter().map(|x| x * 2).collect();
let evens: Vec<_> = vec.into_iter().filter(|x| x % 2 == 0).collect();
// 迭代器方法
let sum: i32 = vec.iter().sum();
let max = vec.iter().max();
let any_gt_3 = vec.iter().any(|&x| x > 3);
// 分块处理
for chunk in vec.chunks(2) {
println!("{:?}", chunk); // [1,2], [3,4], [5]
}
6. 实现特质(Trait)
数组特质实现
rust
// 为数组实现自定义特质
trait ArrayStats {
type Item;
fn mean(&self) -> f64;
fn median(&self) -> Self::Item;
}
impl<T: Copy + Into<f64> + Ord> ArrayStats for [T] {
type Item = T;
fn mean(&self) -> f64 {
if self.is_empty() { return 0.0; }
let sum: f64 = self.iter()
.map(|&x| x.into())
.sum();
sum / self.len() as f64
}
fn median(&self) -> T {
let mut sorted = self.to_vec();
sorted.sort();
sorted[sorted.len() / 2]
}
}
// 使用
let arr = [1.0, 2.0, 3.0, 4.0, 5.0];
println!("平均值: {}", arr.mean()); // 3.0
println!("中位数: {}", arr.median()); // 3.0
通用集合特质
rust
use std::ops::{Index, IndexMut};
// 通用索引特质
trait Collection<T> {
fn get(&self, index: usize) -> Option<&T>;
fn len(&self) -> usize;
}
// 为数组和向量实现
impl<T> Collection<T> for [T] {
fn get(&self, index: usize) -> Option<&T> {
self.get(index)
}
fn len(&self) -> usize {
self.len()
}
}
impl<T> Collection<T> for Vec<T> {
fn get(&self, index: usize) -> Option<&T> {
self.get(index)
}
fn len(&self) -> usize {
self.len()
}
}
迭代器适配器特质
rust
trait VectorExtensions<T> {
fn filter_map<U, F>(&self, f: F) -> Vec<U>
where F: Fn(&T) -> Option<U>;
}
impl<T> VectorExtensions<T> for Vec<T> {
fn filter_map<U, F>(&self, f: F) -> Vec<U>
where F: Fn(&T) -> Option<U>
{
self.iter()
.filter_map(f)
.collect()
}
}
// 使用
let nums = vec![1, 2, 3, 4, 5];
let strings: Vec<String> = nums.filter_map(|&x| {
if x % 2 == 0 { Some(x.to_string()) } else { None }
});
// → ["2", "4"]
7. 性能对比:数组 vs 向量
| 特性 | 数组 [T; N] |
向量 Vec<T> |
|---|---|---|
| 大小 | 编译时固定 | 运行时可变 |
| 内存分配 | 栈(通常) | 堆 |
| 性能 | 更快(无分配) | 稍慢(需分配) |
| 边界检查 | 编译时部分检查 | 运行时检查 |
| 灵活性 | 低 | 高 |
| 内存开销 | 无额外开销 | 指针+容量+长度 |
| 适用场景 | 固定大小数据 | 动态集合 |
性能示例
rust
// 栈上数组 - 零分配开销
fn process_array(arr: &[i32; 1000]) -> i32 {
arr.iter().sum() // 编译器可优化
}
// 堆上向量 - 动态分配
fn process_vec(vec: &Vec<i32>) -> i32 {
vec.iter().sum()
}
// 向量预分配优化
let mut vec = Vec::with_capacity(1000);
for i in 0..1000 {
vec.push(i); // 避免重复分配
}
8. 实用模式
栈分配小数组模式
rust
// 小数据使用数组避免堆分配
struct SmallData {
buffer: [u8; 256], // 栈分配,快速
len: usize,
}
impl SmallData {
fn new() -> Self {
SmallData {
buffer: [0; 256],
len: 0,
}
}
}
向量作为缓冲区
rust
// 高效文本处理
fn read_lines() -> Vec<String> {
let mut lines = Vec::new();
// 模拟读取
lines.push("Line 1".to_string());
lines.push("Line 2".to_string());
lines.push("Line 3".to_string());
lines
}
// 批量处理
let mut batch = Vec::with_capacity(100);
for item in 0..100 {
batch.push(item * 2);
}
// 一次性处理整个批次
let sum: i32 = batch.iter().sum();
矩阵运算
rust
// 使用向量实现动态矩阵
struct Matrix {
data: Vec<Vec<f64>>, // 嵌套向量
rows: usize,
cols: usize,
}
impl Matrix {
fn new(rows: usize, cols: usize) -> Self {
Matrix {
data: vec![vec![0.0; cols]; rows],
rows,
cols,
}
}
}
9. 最佳实践
选择指南
- 使用数组:大小固定且小(< 1KB)时
- 使用向量:大小可变、未知或较大时
- 预分配向量 :已知大小时使用
with_capacity - 优先切片参数 :函数接受
&[T]而非&Vec<T>
内存安全技巧
rust
// 避免索引越界
let vec = vec![1, 2, 3];
// 安全方式
if let Some(&val) = vec.get(5) {
// 处理值
}
// 遍历更安全
for (i, &val) in vec.iter().enumerate() {
// 安全访问
}
// 使用迭代器方法
let exists = vec.contains(&2);
let position = vec.iter().position(|&x| x == 3);
10. 核心特质实现
标准库特质
rust
// 数组和向量都实现这些特质
use std::fmt::Debug;
// Debug - 调试输出
println!("{:?}", vec![1, 2, 3]); // [1, 2, 3]
// Clone - 深拷贝
let cloned = vec.clone();
// From/Into - 类型转换
let arr = [1, 2, 3];
let vec: Vec<_> = arr.into(); // 数组转向量
// Default - 默认值
let empty: Vec<i32> = Default::default();
// Deref - 自动解引用为切片
fn takes_slice(slice: &[i32]) {}
takes_slice(&vec); // 自动转换
自定义集合特质
rust
// 定义通用集合操作
trait Container<T> {
fn add(&mut self, item: T);
fn remove_last(&mut self) -> Option<T>;
fn is_empty(&self) -> bool;
}
impl<T> Container<T> for Vec<T> {
fn add(&mut self, item: T) {
self.push(item);
}
fn remove_last(&mut self) -> Option<T> {
self.pop()
}
fn is_empty(&self) -> bool {
self.is_empty()
}
}
总结对比
| 维度 | 数组 | 向量 |
|---|---|---|
| 定义 | [T; N] |
Vec<T> |
| 大小 | 固定(编译时) | 动态(运行时) |
| 内存 | 通常栈上 | 堆上 |
| 性能 | 极快(无分配) | 快(有分配) |
| 灵活性 | 低 | 高 |
| 适用 | 常量数据、缓冲区 | 动态集合、未知大小 |
关键决策点:
- 数据量小且固定 → 数组
- 数据量未知或可变 → 向量
- 性能敏感 → 优先数组,次选预分配向量
- 代码通用 → 使用切片特质
&[T]
两者结合使用,数组处理固定模式,向量处理动态数据,通过特质提供统一接口。