Rust学习笔记:模块系统——mod、use、pub与多文件项目


📝 本文首发于 栏轩·阁

欢迎访问阅读原文,获取更好的阅读体验。


前八篇所有代码都塞在一个 main.rs 里。再写下去谁也维护不了。这一篇讲 Rust 的模块系统------modusepub------把代码合理地拆到多个文件中。


1. 默认私有,pub 公开

Rust 的可见性规则极其简单:所有东西默认私有,加 pub 才公开。

rust 复制代码
mod kitchen {
    fn cook() { println!("做菜"); }      // 私有,外部不可见
    pub fn order() {                     // 公开
        println!("点菜");
        cook();  // 模块内可以访问私有函数
    }
}

// kitchen::cook();   // ❌ 私有
kitchen::order();      // ✅ 公开

C 语言里函数默认全局可见,Rust 反过来。好处是接口清晰------你看到 pub 就知道这是对外承诺的 API,剩下的都是内部实现。


2. 三种模块形态

2.1 行内模块

rust 复制代码
mod inline {
    pub fn greet() {
        println!("Hello!");
    }
}

fn main() {
    inline::greet();
}

2.2 文件模块

mod my_module; → 编译器找 src/my_module.rs

rust 复制代码
// main.rs
mod my_module;
use my_module::eat;

// src/my_module.rs
pub fn eat() { println!("吃饭"); }

2.3 目录模块(含子模块)

复制代码
src/
├── main.rs
└── nested/
    ├── mod.rs        # 目录模块的入口
    └── inner.rs      # 子模块
rust 复制代码
// nested/mod.rs
pub mod inner;
pub mod outer { pub fn show() {} }

三种形态可以混搭。文件多了就用目录,文件少就用单文件。


3. use:简化路径

不想每次都写完整路径,就用 use 引入:

rust 复制代码
mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
        pub fn seat_at_table() {}
    }
}

// 不用 use:每次都要写全路径
front_of_house::hosting::add_to_waitlist();

// 用 use:简化
use front_of_house::hosting;
hosting::add_to_waitlist();
hosting::seat_at_table();

路径分两种:

路径类型 写法 含义
绝对路径 crate::front_of_house::hosting 从 crate 根开始
相对路径 front_of_house::hosting 从当前模块开始

4. 结构体字段的可见性

pub 可以精细到字段级别:

rust 复制代码
pub struct Breakfast {
    pub toast: String,   // 公开
    fruit: String,       // 私有
}

外部可以读写 breakfast.toast,但碰不到 fruit。这种设计让结构体可以在保证内部不变式的同时暴露部分字段。


5. 实战:餐厅示例

用餐厅场景把模块系统串起来------模拟 Rust 官方书中的例子:

项目结构:

复制代码
src/
├── main.rs
├── my_module.rs      # 餐厅业务逻辑
└── nested/
    ├── mod.rs
    └── inner.rs

模块层次:

复制代码
crate
├── inline (行内模块)
├── my_module (文件模块)
│   ├── front_of_house::hosting (子模块)
│   └── back_of_house (子模块)
└── nested (目录模块)
    ├── outer
    └── inner

crate 是 Rust 中「当前项目」的根。crate::my_module::front_of_house::hosting 就是「从这个项目根开始的绝对路径」。


6. 一个容易踩的坑

moduse 不是一回事。

rust 复制代码
mod my_module;     // 声明模块存在,编译器去找对应文件
use my_module::fn; // 引入路径,简化调用

C 程序员容易把 use#include 用,但实际上 mod 才是「引入代码」,use 只是「起别名/缩短路径」。先 mod 声明模块,再 use 引入其中的内容。


总结

关键字 作用 C 对应物
mod 声明模块,引入文件 #include / 编译单元
pub 公开可见 默认全局(Rust 相反)
use 引入路径,简化调用 using / import
crate 绝对路径的根 项目根命名空间

模块系统搞定之后,Rust 基础语法的最后一块拼图就齐了。下一篇也是本系列的收尾篇------Cargo 依赖管理:怎么引用第三方 crate、版本号怎么写、Cargo.toml 怎么配。

相关推荐
Amos_Web2 小时前
Rspack 源码解析(十二):JavaScript Chunk 是如何被渲染出来的
前端·rust·源码
柯南46682 小时前
【AI开发之Rust】第 14 课:网络请求与 JSON —— reqwest + serde
rust·编程语言
恋喵大鲤鱼3 小时前
Rust 格式化输出占位符详解
rust
孙启超3 小时前
【AI开发之Rust】第 13 课:async/await 与 tokio 异步运行时
开发语言·后端·rust
小道士写程序3 小时前
Rust + Axum + MySQL + SQLx
rust
mikuyyds20 小时前
geo-toolbox 插件算法解析:RUSLE 与 MUSLE 的工程化落地
算法·rust·gis
qq_4523962321 小时前
第十四篇:《系统编程实战:用 Rust 编写高性能 HTTP 服务器》
rust
Amos_Web1 天前
Rspack 源码解析(十一):资产 Hook 与增量构建
前端·rust·源码阅读