Skip to content

复合类型

> 学习元组和数组两种复合类型,掌握固定大小集合的创建、访问与解构。

元组(Tuple)

概念名称: 元组是固定长度的复合类型,可包含不同类型的值。

语法结构:
┌──────────────────────────────────────┐
│  (类型1, 类型2, 类型3, ...)          │
│                                       │
│  let point: (i32, i32) = (1, 2);     │
│  let mixed = (42, "hi", true);       │
│                                       │
│  解构:let (x, y) = point;           │
│  索引:point.0, point.1              │
└──────────────────────────────────────┘

为什么用它?

rust
// 没有元组:需要定义结构体才能返回多个值
struct Result { min: i32, max: i32 }
fn min_max(numbers: &[i32]) -> Result { ... }

// 有元组:轻量级返回多个值
fn min_max(numbers: &[i32]) -> (i32, i32) { ... }
let (min, max) = min_max(&numbers);
▶ Run

最简示例

rust
fn main() {
    let point = (1, 2);
    let (x, y) = point;
    println!("x={}, y={}", x, y);
}
▶ Run

详细示例

rust
fn main() {
    // 创建元组
    let point: (i32, i32, i32) = (1, 2, 3);
    let mixed = (42, "hello", true);

    println!("point = {:?}", point);
    println!("mixed = {:?}", mixed);

    // 方法 1:模式匹配解构
    let (x, y, z) = point;
    println!("x = {}, y = {}, z = {}", x, y, z);

    // 只取部分值(用_忽略其他)
    let (first, _, _) = point;
    println!("first = {}", first);

    // 方法 2:索引访问
    println!("point.0 = {}", point.0);
    println!("point.1 = {}", point.1);

    // 交换两个值(不用临时变量)
    let mut a = 10;
    let mut b = 20;
    (a, b) = (b, a);
    println!("交换后:a = {}, b = {}", a, b);
}
▶ Run

关键代码说明:

代码含义为什么这样写
(i32, i32, i32)元组类型固定长度,可包含不同类型
let (x, y, z) = point解构一次性提取所有元素
point.0索引访问从 0 开始,编译时检查
_忽略占位符不需要的元素用 _ 忽略

元组作为函数返回值

rust
// 返回多个值的函数
fn min_max(numbers: &[i32]) -> (i32, i32) {
    let mut min = numbers[0];
    let mut max = numbers[0];

    for &n in numbers.iter() {
        if n < min { min = n; }
        if n > max { max = n; }
    }

    (min, max)
}

fn main() {
    let numbers = [3, 1, 4, 1, 5, 9, 2, 6];
    let (min, max) = min_max(&numbers);
    println!("最小值:{},最大值:{}", min, max);
}
▶ Run

数组(Array)

概念名称: 数组是固定长度的同类型元素集合。

语法结构:
┌──────────────────────────────────────┐
│  [类型; 长度]  或  [值1, 值2, ...]   │
│                                       │
│  let arr: [i32; 3] = [1, 2, 3];      │
│  let zeros = [0; 5];  → [0,0,0,0,0]  │
│                                       │
│  访问:arr[0], arr.get(0)             │
└──────────────────────────────────────┘

为什么用它?

rust
// 没有数组:需要单独变量
let a1 = 10;
let a2 = 20;
let a3 = 30;

// 有数组:统一管理,可迭代
let numbers = [10, 20, 30];
for n in &numbers {
    println!("{}", n);
}
▶ Run

最简示例

rust
fn main() {
    let numbers = [1, 2, 3, 4, 5];
    println!("第一个:{}", numbers[0]);
    println!("长度:{}", numbers.len());
}
▶ Run

详细示例

rust
fn main() {
    // 类型推断
    let numbers = [1, 2, 3, 4, 5];

    // 显式类型标注
    let floats: [f64; 4] = [1.0, 2.0, 3.0, 4.0];

    // 重复元素(语法糖)
    let zeros = [0; 5];      // [0, 0, 0, 0, 0]
    let names = ["Alice"; 3]; // ["Alice", "Alice", "Alice"]

    println!("numbers = {:?}", numbers);
    println!("zeros = {:?}", zeros);
    println!("names = {:?}", names);

    // 数组长度(编译时已知)
    println!("numbers 长度:{}", numbers.len());
}
▶ Run

关键代码说明:

代码含义为什么这样写
[i32; 5]数组类型类型 + 长度,编译时确定
[0; 5]重复语法快速创建相同元素的数组
numbers.len()数组长度编译时常量,无运行时开销

访问数组元素

rust
fn main() {
    let numbers = [10, 20, 30, 40, 50];

    // 索引访问(从 0 开始)
    let first = numbers[0];
    let last = numbers[4];

    println!("第一个:{},最后一个:{}", first, last);

    // 安全访问(使用 get 方法)
    match numbers.get(2) {
        Some(value) => println!("索引 2 的值:{}", value),
        None => println!("索引不存在"),
    }

    // 越界访问返回 None(而不是 panic)
    match numbers.get(10) {
        Some(value) => println!("{}", value),
        None => println!("索引 10 超出范围"),
    }
}
▶ Run

小结

  • 元组(Tuple):可包含不同类型,固定长度,用 .0/.1 或解构访问
  • 数组(Array):同类型元素,固定长度,用 [T; N] 声明
  • 元组适合返回多个不同类型值,数组适合同类型的固定集合
  • 动态大小集合请使用 Vec<T>(后续章节)

练习题

详见:练习题