【Rust】05-结构体、枚举与模式匹配

结构体、枚举与模式匹配

学习目标

  • 使用结构体组织相关数据。
  • 使用枚举表达有限状态。
  • 掌握 matchif let 的基本用法。

结构体

结构体用于给一组相关字段命名:

rust 复制代码
struct User {
    name: String,
    email: String,
    active: bool,
}

fn main() {
    let user = User {
        name: String::from("Alice"),
        email: String::from("alice@example.com"),
        active: true,
    };

    println!("{} <{}>", user.name, user.email);
}

字段默认不可变。如果需要修改字段,整个结构体绑定必须是 mut

rust 复制代码
let mut user = User {
    name: String::from("Alice"),
    email: String::from("alice@example.com"),
    active: true,
};

user.active = false;

Rust 不支持只把某个字段标记为可变。

字段初始化简写

当变量名和字段名相同时,可以简写:

rust 复制代码
struct User {
    name: String,
    email: String,
}

fn build_user(name: String, email: String) -> User {
    User { name, email }
}

结构体更新语法

可以基于已有结构体创建新值:

rust 复制代码
struct Settings {
    theme: String,
    page_size: u32,
    notifications: bool,
}

fn main() {
    let default = Settings {
        theme: String::from("light"),
        page_size: 20,
        notifications: true,
    };

    let custom = Settings {
        theme: String::from("dark"),
        ..default
    };

    println!("{}", custom.theme);
}

注意:如果被移动的字段不是 Copy,使用 ..default 后,default 可能不再完整可用。

方法

使用 impl 给结构体定义方法:

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

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
}

fn main() {
    let rect = Rectangle {
        width: 30,
        height: 50,
    };

    println!("{}", rect.area());
}

&selfself: &Self 的简写,表示方法借用当前实例。

枚举

枚举用于表达一个值只能是若干变体之一:

rust 复制代码
enum Direction {
    Up,
    Down,
    Left,
    Right,
}

枚举变体可以携带数据:

rust 复制代码
enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(u8, u8, u8),
}

这让枚举非常适合表达状态机、命令、协议消息和错误类型。

match

match 会穷尽处理所有可能分支:

rust 复制代码
enum Direction {
    Up,
    Down,
    Left,
    Right,
}

fn describe(direction: Direction) -> &'static str {
    match direction {
        Direction::Up => "go up",
        Direction::Down => "go down",
        Direction::Left => "go left",
        Direction::Right => "go right",
    }
}

如果遗漏某个分支,编译器会报错。

if let

当只关心一个模式时,可以使用 if let

rust 复制代码
fn main() {
    let value = Some(3);

    if let Some(number) = value {
        println!("number={number}");
    }
}

这比只为了处理一个分支写完整 match 更简洁。

常见误区

  • 结构体字段可变性由变量绑定决定,不由字段单独决定。
  • match 必须穷尽所有情况,这是优点,不是麻烦。
  • 枚举不是只能表示无数据标签;它的变体可以携带不同形状的数据。
  • if let 适合单分支,复杂逻辑仍建议使用 match

练习

  1. 定义一个 Book 结构体,包含标题、作者和页数。
  2. Book 实现一个 summary 方法。
  3. 定义一个 TaskStatus 枚举,包含 TodoDoingDone,用 match 打印状态说明。

后记

2026年6月10日17点14分于上海。

相关推荐
星栈1 小时前
Makepad 应用如何读文件、调接口、保存数据
前端·rust
cjp5601 小时前
006.WEB_API使用本地数据库 SQLite + Dapper 入门教程
数据库·sqlite
阿正的梦工坊1 小时前
【Rust】10-Cargo、测试与实用开发工作流
java·rust·log4j
用户298698530141 小时前
Java 实战:Word 文档中超链接的添加与自定义技巧
java·后端
新新学长搞科研1 小时前
【广东省博促会主办】2026年第七届先进材料与智能制造国际学术会议(ICAMIM 2026)
大数据·前端·数据库·人工智能·物联网
睡不醒男孩0308231 小时前
CLup篇之PostgreSQL管理
数据库·postgresql
瀚高PG实验室1 小时前
数据库启动报错:42501: 无法打开共享内存段 “/PostgreSQL.******“: 权限不够
数据库·postgresql·瀚高数据库
swordbob1 小时前
Spring事务失效的场景
java·开发语言·spring
Devin~Y1 小时前
大厂 Java 面试实战:从 Spring Boot 微服务到 AI RAG 音视频平台全链路解析
java·spring boot·redis·spring cloud·微服务·rag·spring ai