Rust 数组类型详解 - 来自 rust-by-practice 的实践指南
数组是 Rust 中最基础也是最常用的复合数据类型之一。本文将深入讲解 Rust 数组的特性、用法以及常见问题,帮助开发者掌握这一重要数据结构。
数组的基本特性
Rust 数组的类型签名是 [T; Length]
,其中:
T
表示数组元素的类型Length
表示数组长度,必须是编译期已知的常量
这种设计意味着数组长度是其类型的一部分,编译器需要在编译时就知道数组的确切大小。例如下面的代码会报错:
fn init_arr(n: i32) {
let arr = [1; n]; // 错误:n 不是编译期常量
}
数组声明与初始化
显式类型声明
let arr: [i32; 5] = [1, 2, 3, 4, 5];
类型推断
Rust 允许省略部分或全部类型信息:
let arr0 = [1, 2, 3]; // 编译器推断为 [i32; 3]
let arr: [_; 3] = ['a', 'b', 'c']; // 元素类型由编译器推断
统一值初始化
所有元素初始化为相同值的简便语法:
let list: [i32; 100] = [1; 100]; // 100个1组成的数组
数组内存布局
Rust 数组是栈分配的,其大小在编译时确定。可以通过 std::mem::size_of_val
获取数组占用的字节数:
let arr: [char; 3] = ['a', 'b', 'c'];
assert!(std::mem::size_of_val(&arr) == 12); // 每个char占4字节
注意:Rust 中的 char
是 Unicode 标量值,固定占用 4 字节。
数组元素访问
索引访问
Rust 数组使用从 0 开始的索引:
let arr = ['a', 'b', 'c'];
let ele = arr[0]; // 第一个元素
越界检查
Rust 会在运行时检查数组越界访问,越界会导致 panic:
let names = [String::from("Sunfei"), "Sunface".to_string()];
let name0 = names.get(0).unwrap(); // 安全,返回Option
let _name1 = &names[2]; // 越界,panic!
建议使用 get
方法进行安全访问,它返回 Option<T>
类型。
类型一致性要求
Rust 数组要求所有元素必须是相同类型:
let _arr = [1, 2, '3']; // 错误:混合了i32和char类型
实践建议
- 优先使用固定大小集合:当集合大小在编译期已知时,数组是最佳选择
- 考虑使用切片:当需要处理动态大小的数据时,考虑使用切片类型
&[T]
- 注意字符类型大小:Rust 的
char
占用 4 字节,与 C/C++ 不同 - 安全访问:不确定索引是否有效时,使用
get
方法而非直接索引
通过掌握这些数组特性,你可以在 Rust 中高效地处理固定大小的数据集合。记住 Rust 的编译期检查虽然严格,但能帮助避免许多运行时错误。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考