结构体 (struct)

前置知识点回顾
Rust 使用 struct 定义结构体,分为三类:

  1. 经典C风格命名结构体(命名字段)
  2. 元组结构体 Tuple Struct(带结构体名称的元组)
  3. 单元结构体 Unit Struct(无任何字段,泛型场景常用)

基础普通结构体

// 屏蔽未使用代码警告
#![allow(dead_code)]

// 派生Debug trait,支持 {:?} 打印结构体
#[derive(Debug)]
struct Person {
    name: String,
    age: u8,
}

fn main() {
    let name = String::from("Jack");
    let age = 27;

    // 字段初始化简写:变量名和结构体字段名一致时,可以直接简写
    let jack = Person { name, age };

    // 使用Debug格式化打印整个结构体
    println!("{:?}", jack );
}Code language: Rust (rust)

运行输出

Person { name: "jack ", age: 27 }Code language: CSS (css)

解析

  1. #[derive(Debug)]:自动实现 Debug trait,允许用 {:?} 格式化输出结构体;不加会编译报错。
  2. 字段简写语法Person { name, age } 等价于 Person { name: name, age: age },变量名和字段同名时使用。
  3. String 是拥有所有权的字符串类型,不要和 &str 混淆。

结构体字段访问

#![allow(dead_code)]

#[derive(Debug)]
struct Point {
    x: f32,
    y: f32,
}

fn main() {
    // 实例化结构体
    let point = Point { x: 5.2, y: 0.4 };
    let another_point = Point { x: 10.3, y: 0.2 };

    // . 语法直接访问结构体字段
    println!("point coordinates: ({}, {})", point.x, point.y);

    // 结构体更新语法 ..other
    // 手动指定x,剩余所有字段从 another_point 复制
    let bottom_right = Point { x: 10.3, ..another_point };

    println!("second point: ({}, {})", bottom_right.x, bottom_right.y);
}Code language: PHP (php)

运行输出

point coordinates: (5.2, 0.4)
second point: (10.3, 0.2)Code language: CSS (css)

解析

  1. 结构体.字段名:读取结构体内部成员。
  2. ..another_point 结构体更新语法:复制另一个结构体所有未显式赋值的字段。
  3. 所有权注意:如果结构体内部包含所有权类型(String),使用更新语法会转移原结构体所有权。

let 结构体解构

#![allow(dead_code)]

struct Point {
    x: f32,
    y: f32,
}

fn main() {
    let point = Point { x: 5.2, y: 0.4 };

    // 结构体解构:把字段值绑定到新变量 left_edge、top_edge
    let Point { x: left_edge, y: top_edge } = point;

    println!("x = {}, y = {}", left_edge, top_edge);

    // 简化写法:变量名和字段同名
    let Point { x, y } = point;
    println!("x = {}, y = {}", x, y);
}Code language: JavaScript (javascript)

运行输出

x = 5.2, y = 0.4
x = 5.2, y = 0.4

解析

  • let Point { x: left_edge, y: top_edge } = point
    将 point.x 赋值给 left_edge,point.y 赋值给 top_edge

结构体嵌套

结构体作为另一个结构体的字段

#![allow(dead_code)]

struct Point {
    x: f32,
    y: f32,
}

struct Rectangle {
    top_left: Point,
    bottom_right: Point,
}

fn main() {
    let point = Point { x: 5.2, y: 0.4 };
    let another_point = Point { x: 10.3, y: 0.2 };

    // 解构point
    let Point { x: left_edge, y: top_edge } = point;
    let bottom_right = Point { x: 10.3, ..another_point };

    // 结构体嵌套:Rectangle内部存放两个Point
    let _rectangle = Rectangle {
        top_left: Point { x: left_edge, y: top_edge },
        bottom_right: bottom_right,
    };

    // 访问嵌套结构体字段
    println!("矩形右上角x:{}", _rectangle.top_left.x);
}Code language: JavaScript (javascript)

解构:把复合容器(结构体 / 元组 / 数组)内部包裹的值拆出来,绑定到左边一堆独立变量上。

运行输出

矩形右上角x:5.2Code language: CSS (css)

解析

  1. 结构体可以互相嵌套,结构体实例本身也是合法表达式,可以直接作为字段值。
  2. 访问嵌套字段:_rectangle.top_left.x 连续使用 .
  3. 变量名加下划线 _rectangle:告诉编译器“定义了但是故意不使用”,消除未使用变量警告。

单元结构体 Unit Struct

文件名:struct_05_unit_struct.rs

#![allow(dead_code)]

// 单元结构体:没有任何字段
struct Unit;

fn main() {
    // 实例化单元结构体,不需要括号、不需要字段
    let _unit = Unit;

    println!("成功创建单元结构体实例");
}Code language: JavaScript (javascript)

输出

成功创建单元结构体实例

解析

  1. 定义:struct Unit;
  2. 创建实例:Unit,不需要大括号/圆括号。
  3. 使用场景:
  • 实现 trait 但不需要保存任何数据;
  • 泛型标记类型。
  1. 单元结构体默认大小为 0。

元组结构体 Tuple Struct

#![allow(dead_code)]

// 元组结构体:有结构体名称,内部是一组有序类型,没有字段名
struct Pair(i32, f32);

fn main() {
    // 实例化元组结构体,类似元组
    let pair = Pair(1, 0.1);

    // 使用 .索引 访问成员,和普通元组一致 .0 .1 .2...
    println!("pair 第一个值: {:?}, 第二个值: {:?}", pair.0, pair.1);

    // 元组结构体解构
    let Pair(integer, decimal) = pair;
    println!("解构结果:{} , {}", integer, decimal);
}Code language: JavaScript (javascript)

运行输出

pair 第一个值: 1, 第二个值: 0.1
解构结果:1 , 0.1Code language: CSS (css)

解析

  1. 元组结构体和普通元组最大区别:拥有独立类型
  • Pair(i32,f32)(i32,f32) 是两种完全不同类型,不能互相赋值。
  1. 访问方式:.0 .1 数字索引。
  2. 解构语法和普通元组类似 let Pair(a,b) = pair;

三种结构体

类型定义格式实例写法访问方式
命名结构体struct S{a:T,b:U}S{a:1,b:2}s.a
元组结构体struct S(T,U)S(1,2)s.0
单元结构体struct S;S无字段

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注