Rust中数组简介

数组(Array)是一种固定大小的、相同类型元素的集合:

  • 固定长度:长度在编译时确定,无法动态改变;数组的长度 N 是类型的一部分(如 [i32; 5][i32; 6] 是完全不同的类型)。
  • 栈上分配:内存直接分配在栈上(与堆分配的 Vec<T>不同);且是连续存储,因此访问速度快,但不适合存储大量数据(栈空间有限)。
  • 类型安全:所有元素必须是同一类型。
  • 边界检查:访问时自动检查索引是否越界(panic 保护)。

定义与初始化

数组的语法形式为 [T; N]

  • T 是数组中元素的类型(所有元素必须是同一类型);
  • N 是数组的长度(必须是编译时已知的整数常量,不可动态修改)。

初始化方式可以:

  • 直接初始化:列出所有元素初始化数组(元素数量需与指定长度一致);
  • 重复值初始化:使用 [值; 长度]可初始化数组元素为全部相同的值;
  • 默认值初始化:使用默认值初始化数组(需要元素实现Default)
// 定义一个包含5个i32类型元素的数组
let nums: [i32; 5] = [1, 2, 3, 4, 5];
// 类型可省略(编译器会自动推断)
let fruits = ["apple", "banana", "cherry"]; // 类型为 [&str; 3]

// 创建一个包含10个0的i32数组
let zeros = [0; 10]; // 类型为 [i32; 10]
// 创建一个包含3个"hello"的字符串切片数组
let greetings = ["hello"; 3]; // 类型为 [&str; 3]

let arr: [String; 3] = Default::default(); // ["", "", ""]

空数组

空数组(empty array)是合法的,其长度为 0:

let empty1: [i32; 0] = [];
let empty2 = [(); 0]; // 0 个 unit 类型元素
let empty3 = [0; 0];  // 重复 0 次,结果也是空数组

注意:[expr; 0] 是允许的,但 expr 仍会被求值一次然后立即丢弃。

空数组不包含任何元素,但在某些场景下非常有用

  • 泛型编程中的占位符;
  • 满足类型系统要求:API需要传入数组,而没有数据时;
  • 零成本抽象:不占用栈空间,编译器可完全优化掉,适合用于标记或类型级编程;
  • 与 FFI 或底层内存操作配合

访问

Rust 不允许在安全代码中使用未初始化的内存。尝试访问一个未初始化的数组,编译器会报错或导致未定义行为。

索引访问

数组元素通过索引访问,索引从 0 开始。Rust 会在运行时检查索引是否越界,若越界会直接触发程序崩溃(panic)。

数组默认是不可变的,若需修改元素,需要使用mut声明为可变数组:

let mut nums = [1, 2, 3];
nums[1] = 20; // 修改第二个元素
println!("修改后:{:?}", nums); // 输出:[1, 20, 3]

遍历

通过for循环或迭代器可遍历数组:

// 使用 for 循环
for element in &arr {
    println!("{}", element);
}

// 使用迭代器
arr.iter().for_each(|x| println!("{}", x));

常用方法

常用基础方法:

方法功能描述
fn len(&self) -> usize返回数组长度
fn is_empty(&self) -> bool检查数组是否为空
fn iter(&self) -> Iter<T>创建不可变迭代器
fn iter_mut(&mut self) -> IterMut<T>创建可变迭代器
fn as_slice(&self) -> &[T]将数组转换为切片
fn as_mut_slice(&mut self) -> &mut [T]将数组转换为可变切片
fn map<F, U>(self, f: F) -> [U; N]元素映射转换

元素访问

方法功能描述
fn get<I>(&self, index: I) -> Option<&T>安全索引访问
fn get_mut<I>(&mut self, index: I) -> Option<&mut T>安全可变索引访问
fn first(&self) -> Option<&T>获取第一个元素
fn last(&self) -> Option<&T>获取最后一个元素
fn first_mut(&mut self) -> Option<&mut T>获取可变首元素
fn last_mut(&mut self) -> Option<&mut T>获取可变尾元素

操作与转换

方法功能描述
fn swap(&mut self, a: usize, b: usize)交换两个位置的元素
fn reverse(&mut self)反转数组元素顺序
fn fill(&mut self, value: T)填充相同值
fn clone_from_slice(&mut self, src: &[T])从切片克隆数据(需等长)
fn copy_from_slice(&mut self, src: &[T])从切片复制数据(需Copy trait)

搜索与判断方法

方法签名功能描述
fn contains(&self, x: &T) -> bool检查是否包含元素(需PartialEq)
fn starts_with(&self, needle: &[T]) -> bool检查前缀
fn ends_with(&self, needle: &[T]) -> bool检查后缀
fn binary_search(&self, x: &T) -> Result<usize, usize>二分查找(需有序)

数组切片

数组本身长度固定,但其切片(&[T])是动态长度的视图,可灵活处理数组的部分元素。切片是数组的引用,不拥有数据所有权,常用于函数参数传递(兼容不同长度的数组)。

let nums = [1, 2, 3, 4, 5];

// 截取从索引1到3(不包含3)的元素,生成切片
let slice = &nums[1..3]; // 类型为 &[i32],值为 [2, 3]

// 函数接受切片作为参数(可处理任意长度的i32数组)
fn print_slice(slice: &[i32]) {
    println!("切片内容:{:?}", slice);
}

print_slice(&nums); // 传递整个数组的切片,输出:[1, 2, 3, 4, 5]
print_slice(slice); // 传递部分切片,输出:[2, 3]

常用方法

方法功能描述示例
fn windows(&self, size: usize) -> Windows<T>滑动窗口迭代器[1,2,3].windows(2)[1,2], [2,3]
fn chunks(&self, size: usize) -> Chunks<T>固定大小分块迭代器[1,2,3,4].chunks(2)[1,2], [3,4]
fn split_at(&self, mid: usize) -> (&[T], &[T])分割数组为两个切片[1,2,3].split_at(1)(&[1], &[2,3])
fn split_first(&self) -> Option<(&T, &[T])>分离首元素和剩余部分[1,2].split_first()(Some(&1), &[2])
fn split_last(&self) -> Option<(&T, &[T])>分离尾元素和剩余部分[1,2].split_last()(Some(&2), &[1])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值