【Rust】数组与向量:集合类型全解

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. 最佳实践

选择指南

  1. 使用数组:大小固定且小(< 1KB)时
  2. 使用向量:大小可变、未知或较大时
  3. 预分配向量 :已知大小时使用 with_capacity
  4. 优先切片参数 :函数接受 &[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]

两者结合使用,数组处理固定模式,向量处理动态数据,通过特质提供统一接口。

复制代码
相关推荐
唐装鼠6 小时前
Rust Box<T> 和引用(deepseek)
开发语言·rust
Source.Liu6 小时前
【Rust】结构体(Struct)详解
rust
isyuah7 小时前
Miko v0.7 发布:我写的一个 Rust Web 框架,虽然还是个玩具
后端·rust
isyuah7 小时前
Miko 框架系列(十四):集成测试
后端·rust
唐装鼠8 小时前
Rust Turbofish 语法详解(deepseek)
开发语言·后端·rust
Source.Liu8 小时前
【Rust】字符串类型全览:从 UTF-8 到系统路径
rust
唐装鼠8 小时前
Rust 中的 `parse` 方法详解(deepseek)
开发语言·后端·rust
唐装鼠8 小时前
Rust 自动引用规则完全指南(deepseek)
开发语言·后端·rust
唐装鼠8 小时前
Rust Borrow 和 BorrowMut(deepseek)
rust