【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]

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

复制代码
相关推荐
DongLi012 天前
rustlings 学习笔记 -- exercises/05_vecs
rust
番茄灭世神3 天前
Rust学习笔记第2篇
rust·编程语言
shimly1234563 天前
(done) 速通 rustlings(20) 错误处理1 --- 不涉及Traits
rust
shimly1234563 天前
(done) 速通 rustlings(19) Option
rust
@atweiwei3 天前
rust所有权机制详解
开发语言·数据结构·后端·rust·内存·所有权
shimly1234563 天前
(done) 速通 rustlings(24) 错误处理2 --- 涉及Traits
rust
shimly1234563 天前
(done) 速通 rustlings(23) 特性 Traits
rust
shimly1234563 天前
(done) 速通 rustlings(17) 哈希表
rust
shimly1234563 天前
(done) 速通 rustlings(15) 字符串
rust
shimly1234563 天前
(done) 速通 rustlings(22) 泛型
rust