从零开始学Rust:结构体(struct)详解

发布于:2025-04-02 ⋅ 阅读:(25) ⋅ 点赞:(0)

1. 基本结构体定义

结构体是Rust中自定义的数据类型,用于将相关联的数据组合在一起。例如定义一个用户结构体:

struct User {
    username: String,    // 用户名
    email: String,       // 邮箱
    sign_in_count: u64,  // 登录次数
    active: bool,        // 是否活跃
}

重要特性:

  • 可以包含不同类型的数据字段
  • 整个实例必须是可变的(不能单独标记某个字段)
  • 如果实例声明为mut,则可以修改其字段
let mut user1 = User {
    email: String::from("someone@example.com"),
    // ...其他字段
};

user1.email = String::from("new@example.com"); // 允许修改

2. 字段初始化简写

当变量名与字段名相同时,可以使用简写语法:

fn build_user(email: String, username: String) -> User {
    User {
        email,    // 等同于 email: email
        username, // 等同于 username: username
        active: true,
        sign_in_count: 1,
    }
}

3. 结构体更新语法

基于已有结构体创建新结构体,使用…语法:

let user2 = User {
    email: String::from("another@example.com"),
    username: String::from("newuser"),
    ..user1  // 复制user1的剩余字段
};

4. 元组结构体和无字段结构体

元组结构体:有名字的元组

struct Color(i32, i32, i32);
let black = Color(0, 0, 0);

无字段结构体(单元结构体):用于实现trait等场景

struct EmptyStruct;

5. 结构体使用示例

使用元组重构

fn area(dimensions: (u32, u32)) -> u32 {
    dimensions.0 * dimensions.1
}

使用结构体重构(更清晰)

struct Rectangle {
    width: u32,
    height: u32,
}

fn area(rectangle: &Rectangle) -> u32 {
    rectangle.width * rectangle.height
}

6. 打印结构体

使用#[derive(Debug)]实现调试打印:

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

println!("rect1 is {:?}", rect1);       // 单行打印
println!("rect1 is {:#?}", rect1);     // 美化多行打印

7. 方法

方法与函数的区别:

  • 定义在结构体的impl块中
  • 第一个参数总是self(表示结构体实例)
impl Rectangle {
    // 方法 - 有self参数
    fn area(&self) -> u32 {
        self.width * self.height
    }
    
    // 关联函数 - 没有self参数
    fn square(size: u32) -> Rectangle {
        Rectangle {
            width: size,
            height: size,
        }
    }
}

// 调用方法
rect1.area();

// 调用关联函数
let sq = Rectangle::square(10);

关键点:

  • &self表示不可变借用
  • &mut self表示可变借用
  • self表示获取所有权(较少使用)
  • 关联函数(没有self)常用于构造函数

Rust会自动处理方法的引用/解引用,所以不需要像C++那样的 → \rightarrow 操作符。


网站公告

今日签到

点亮在社区的每一天
去签到