一、Struct 是什么?

Struct(结构体)是 Rust 中自定义的复合数据类型,用于将多个不同类型的值组合成一个逻辑整体,用于封装相关数据和行为。它类似于其他语言中的类(class),但更注重数据的封装,而不是行为的封装。

示例:定义一个用户结构体

rust 复制代码
struct User {
    username: String,
    email: String,
    active: bool,
    sign_in_count: u64,
}

这里把用户信息打包成一个整体,包含用户名、邮箱、激活状态和登录次数。


二、Struct 的分类

Rust 的结构体分为三种形式,适用于不同场景:

  1. 具名结构体(Named Struct)
    特点:每个字段都有明确的名称,适合复杂数据。

    rust 复制代码
    struct Point { x: i32, y: i32 }  // 定义
    let p = Point { x: 10, y: 20 };  // 实例化
    println!("坐标:({}, {})", p.x, p.y);  // 访问字段
  2. 元组结构体(Tuple Struct)
    特点:字段通过位置访问(类似元组),适合轻量数据分组。

    rust 复制代码
    struct Color(i32, i32, i32);  // 定义
    let black = Color(0, 0, 0);    // 实例化
    println!("RGB: {}, {}, {}", black.0, black.1, black.2);  // 通过索引访问
  3. 单元结构体(Unit Struct)
    特点:无字段,常用于标记类型或实现 Trait。

    rust 复制代码
    struct UnitMarker;  // 定义
    let marker = UnitMarker;  // 实例化

三、方法(Methods)和实现(Impl)

通过 impl 块为结构体添加方法,分为两类:

  1. 实例方法:操作具体实例,参数为 &self(不可变)或 &mut self(可变)。
  2. 关联函数:类似构造函数,无 self 参数,通过 :: 调用。

示例:为矩形结构体添加方法

rust 复制代码
struct Rectangle { width: u32, height: u32 }

impl Rectangle {
    // 关联函数(构造函数)
    fn new(w: u32, h: u32) -> Self {
        Self { width: w, height: h }
    }

    // 实例方法:计算面积
    fn area(&self) -> u32 {
        self.width * self.height
    }

    // 实例方法:判断是否能包含另一个矩形
    fn can_contain(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }
}

// 使用
let rect1 = Rectangle::new(30, 50);
let rect2 = Rectangle { width: 20, ..rect1 };  // 更新语法(部分字段继承)
println!("面积:{}", rect1.area());

四、应用场景

  1. 数据封装
    例如,用 User 结构体统一管理用户信息,避免分散的变量。
  2. 面向对象设计
    通过方法实现数据的行为,比如矩形的面积计算。
  3. 类型安全
    用元组结构体区分相同数据类型的含义(如 UserId(u32)OrderId(u32))。
  4. 标记和泛型
    单元结构体常用于标记类型或作为泛型占位符。

五、注意事项

  1. 所有权问题
    若字段包含 String 等所有权类型,结构体实例会持有这些数据的所有权。
    示例

    rust 复制代码
    let user = User {
        username: String::from("Alice"),  // 所有权转移给 user
        email: String::from("alice@example.com"),
        // ...
    };
  2. 可变性规则

    • 结构体实例默认不可变,需用 mut 声明可变性:
      rust 复制代码
      let mut user = User { ... };
      user.email = String::from("new@example.com");  // 允许修改
    • 所有字段要么全可变,要么全不可变,不能单独标记某个字段。
  3. 生命周期
    若结构体包含引用字段(如 &str),必须指定生命周期参数:

    rust 复制代码
    struct UserRef<'a> {
        username: &'a str,
        email: &'a str,
    }
  4. 自动派生 Trait
    通过 #[derive] 快速实现常用功能(如调试输出、克隆):

    rust 复制代码
    #[derive(Debug, Clone, PartialEq)]
    struct Point { x: i32, y: i32 }

六、总结

Struct 是 Rust 中组织数据的核心工具,通过三种形式满足不同需求。结合方法和生命周期管理,既能保证数据安全,又能实现灵活的行为逻辑。使用时注意所有权和可变性规则,合理选择结构体类型,可以大幅提升代码的可读性和健壮性。