组织代码:模块与包

原理

Rust 的模块系统是纯编译期概念。编译器将多个 .rs 文件按 mod 声明构建为 crate 树。src/main.rssrc/lib.rs 作为 crate 根(root),编译器以此为起点递归解析模块。

打包层次:Package > Crate > Module

  • Package:包含 Cargo.toml 的目录,可包含 1 个 lib crate + N 个 bin crate
  • Crate:编译单元,rustc 每次编译一个 crate,生成 .rlib(库)或可执行文件
  • Module:代码组织单元,可通过内联或文件系统拆分

pub 修饰符控制可见性。默认 privatepub(crate) 在本 crate 内可见;pub(super) 在父模块可见;pub(in path) 在指定路径可见。

use 语句在编译后不会产生任何代码,只是路径别名(相当于 C++ 的 using)。模块系统不产生运行时开销。

C: 多文件项目
动态库


语法

内联模块

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"
clapCLI 参数"4"
tokio异步运行时"1"

实践

力扣问题

力扣: 力扣结构化编程题 — 多模块拆分

AI 自检

  1. mod x; 发现 x.rsx/mod.rs 同时存在时,编译器如何处理?
  2. pub(crate)pub(super) 的使用场景区别?为何 Rust 设计了层级可见性?