元组与数组
学习目标
- 掌握元组的定义和解构
- 掌握数组的定义和操作
- 理解固定大小和栈分配
- 掌握切片操作
核心概念
元组(Tuple)
fn main() {
let tup: (i32, f64, &str) = (42, 3.14, "hello");
let (x, y, z) = tup;
println!("x={}, y={}, z={}", x, y, z);
println!("{}", tup.0);
println!("{}", tup.1);
println!("{}", tup.2);
let unit: () = ();
}
元组作为函数返回值
fn div_rem(a: i32, b: i32) -> (i32, i32) {
(a / b, a % b)
}
fn main() {
let (quotient, remainder) = div_rem(17, 5);
println!("17 / 5 = {} 余 {}", quotient, remainder);
}
数组(Array)
fn main() {
let arr: [i32; 5] = [1, 2, 3, 4, 5];
let zeros = [0; 10];
let first = arr[0];
let last = arr[arr.len() - 1];
println!("len: {}", arr.len());
for val in &arr {
print!("{} ", val);
}
println!();
for (i, val) in arr.iter().enumerate() {
println!("arr[{}] = {}", i, val);
}
}
数组切片
fn main() {
let arr = [1, 2, 3, 4, 5];
let slice = &arr[1..3];
let all = &arr[..];
let from_two = &arr[2..];
let to_three = &arr[..3];
println!("sum: {}", sum(&arr));
println!("partial sum: {}", sum(&arr[1..4]));
}
fn sum(numbers: &[i32]) -> i32 {
numbers.iter().sum()
}
多维数组
fn main() {
let matrix: [[i32; 3]; 2] = [
[1, 2, 3],
[4, 5, 6],
];
println!("{}", matrix[0][1]);
println!("{}", matrix[1][2]);
}
数组 vs Vec
| 特性 | 数组 [T; N] | Vec Vec<T> |
|---|
| 大小 | 编译时固定 | 运行时动态 |
| 存储 | 栈 | 堆 |
| 性能 | 更快(无堆分配) | 略慢 |
| 适用 | 已知大小 | 未知大小 |
常用方法
fn main() {
let arr = [3, 1, 4, 1, 5, 9, 2, 6];
let pos = arr.iter().position(|&x| x == 5);
let found = arr.iter().any(|&x| x > 8);
let all_positive = arr.iter().all(|&x| x > 0);
let max = arr.iter().max();
let min = arr.iter().min();
let mut arr = [3, 1, 4, 1, 5];
arr.sort();
println!("{:?}", arr);
arr.reverse();
println!("{:?}", arr);
}
实践练习
练习 1:旋转数组
fn rotate_left(arr: &mut [i32], k: usize) {
let n = arr.len();
let k = k % n;
arr.reverse();
arr[..n-k].reverse();
arr[n-k..].reverse();
}
fn main() {
let mut arr = [1, 2, 3, 4, 5];
rotate_left(&mut arr, 2);
println!("{:?}", arr);
}
练习 2:合并有序数组
fn merge_sorted(a: &[i32], b: &[i32]) -> Vec<i32> {
let mut result = Vec::with_capacity(a.len() + b.len());
let mut i = 0;
let mut j = 0;
while i < a.len() && j < b.len() {
if a[i] <= b[j] {
result.push(a[i]);
i += 1;
} else {
result.push(b[j]);
j += 1;
}
}
result.extend_from_slice(&a[i..]);
result.extend_from_slice(&b[j..]);
result
}
fn main() {
let a = [1, 3, 5, 7];
let b = [2, 4, 6, 8];
let merged = merge_sorted(&a, &b);
println!("{:?}", merged);
}
练习 3:矩阵乘法
fn matmul(a: &[[f64; 3]; 3], b: &[[f64; 3]; 3]) -> [[f64; 3]; 3] {
let mut result = [[0.0; 3]; 3];
for i in 0..3 {
for j in 0..3 {
for k in 0..3 {
result[i][j] += a[i][k] * b[k][j];
}
}
}
result
}
fn main() {
let a = [
[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0],
[7.0, 8.0, 9.0],
];
let b = [
[9.0, 8.0, 7.0],
[6.0, 5.0, 4.0],
[3.0, 2.0, 1.0],
];
let c = matmul(&a, &b);
for row in &c {
println!("{:?}", row);
}
}
常见错误
1. 数组越界
let arr = [1, 2, 3];
let x = arr.get(10);
2. 数组大小不匹配
let arr: [i32; 3] = [1, 2, 3];
3. 可变借用
let mut arr = [1, 2, 3];
let slice = &arr[0..2];
println!("{:?}", slice);
小结
| 类型 | 语法 | 特点 |
|---|
| 元组 | (T1, T2, ...) | 不同类型,固定大小 |
| 数组 | [T; N] | 相同类型,固定大小,栈分配 |
| 切片 | &[T] | 动态大小引用 |
元组适合少量异构数据,数组适合同构固定大小序列。