组织代码:模块与包
原理
Rust 的模块系统是纯编译期概念。编译器将多个 .rs 文件按 mod 声明构建为 crate 树。src/main.rs 和 src/lib.rs 作为 crate 根(root),编译器以此为起点递归解析模块。
打包层次:Package > Crate > Module
- Package:包含
Cargo.toml的目录,可包含 1 个 lib crate + N 个 bin crate - Crate:编译单元,rustc 每次编译一个 crate,生成
.rlib(库)或可执行文件 - Module:代码组织单元,可通过内联或文件系统拆分
pub 修饰符控制可见性。默认 private;pub(crate) 在本 crate 内可见;pub(super) 在父模块可见;pub(in path) 在指定路径可见。
use 语句在编译后不会产生任何代码,只是路径别名(相当于 C++ 的 using)。模块系统不产生运行时开销。
语法
内联模块
mod network {
pub fn connect() { }
fn handshake() { } // 私有,外部不可见
}
fn main() {
network::connect();
}可见性控制
| 修饰符 | 可见范围 |
|---|---|
| 无 | 当前模块私有 |
pub | 公开 |
pub(crate) | 当前 crate 内 |
pub(super) | 父模块 |
pub(in path) | 指定路径 |
文件模块
// main.rs
mod animals; // 查找 animals.rs 或 animals/mod.rs// animals.rs
pub struct Dog { pub name: String }
impl Dog { pub fn bark(&self) { } }目录模块
src/
main.rs
school/
mod.rs # pub mod student; pub mod teacher;
student.rs
teacher.rs
use 语句
use std::collections::HashMap; // 单路径
use std::io::{self, Read, Write}; // 多路径(self = io 本身)
use std::collections::*; // 通配符(谨慎使用)
use std::fmt::Result as FmtResult; // 别名(解决冲突)外部依赖
# Cargo.toml
[dependencies]
rand = "0.8"
serde = { version = "1.0", features = ["derive"] }use rand::Rng;
fn main() {
let n = rand::thread_rng().gen_range(1..=100);
}常用库速览
| 库 | 用途 | Cargo.toml |
|---|---|---|
rand | 随机数 | "0.8" |
serde | 序列化 | { version="1.0", features=["derive"] } |
regex | 正则 | "1" |
chrono | 日期时间 | "0.4" |
clap | CLI 参数 | "4" |
tokio | 异步运行时 | "1" |
实践
力扣问题
力扣: 力扣结构化编程题 — 多模块拆分
AI 自检
mod x;发现x.rs和x/mod.rs同时存在时,编译器如何处理?pub(crate)和pub(super)的使用场景区别?为何 Rust 设计了层级可见性?