模块系统、crate 与 workspace intermediate 30 分钟 更新 2026-06-15

模块系统

用 mod、pub 和 use 组织代码,控制可见性。

模块系统

你会学到什么

  • mod 声明模块,模块可以拆成独立文件。
  • 默认私有,用 pub 显式对外暴露。
  • use 把路径引入当前作用域,少写前缀。

最小示例

mod geometry;          // 对应 src/geometry.rs
use geometry::area;    // 引入子模块

fn main() {
    println!("{}", area::rectangle(2.0, 3.0));
}

运行代码

cd examples
cargo run -p rt_28_modules
cargo test -p rt_28_modules

代码讲解

模块树和文件系统对应:mod geometry; 会去找 src/geometry.rs,其中的 pub mod area; 又对应 src/geometry/area.rs

// src/geometry.rs
pub mod area;
pub fn describe() -> &'static str { "geometry module" }

可见性是分层的:只有标了 pub 的项才能被父模块访问。use 只是创建一个简写别名,不改变可见性。路径以 crate:: 开头表示从 crate 根算起,super:: 表示上一层。

常见错误

忘记把要对外使用的项标成 pub:

mod geometry {
    fn area() -> f64 { 1.0 } // 私有
}
geometry::area(); // ❌ function `area` is private

加上 pub fn area

练习

  • geometry 加一个 perimeter 子模块。
  • pub use 把深层函数“重导出”到模块顶层,简化调用路径。

小结

模块系统用 mod/pub/use 把代码分层组织,默认私有的设计让你显式地决定 API 边界。

下一步

把可复用逻辑抽成库 crate,再用 workspace 管理多个 crate。下一章学习库 crate 与 workspace。

完整示例代码

下面是 examples/28_modules/ 的完整源码。无需 clone 仓库,直接在页面上阅读、复制、对照运行。

examples/28_modules/src/main.rs
//! 演示模块系统:mod 声明、pub 可见性、use 引入。

mod geometry;

use geometry::area;

fn main() {
    println!("{}", geometry::describe());
    println!("rectangle = {}", area::rectangle(2.0, 3.0));
    println!("circle = {:.2}", area::circle(1.0));
}

#[cfg(test)]
mod tests {
    use crate::geometry::area;

    #[test]
    fn rectangle_area() {
        assert_eq!(area::rectangle(2.0, 3.0), 6.0);
    }

    #[test]
    fn circle_area() {
        assert!((area::circle(1.0) - std::f64::consts::PI).abs() < 1e-9);
    }
}
examples/28_modules/src/geometry.rs
//! geometry 模块:聚合子模块并暴露公共接口。

pub mod area;

/// 公开函数,可被父模块通过 `geometry::describe()` 调用。
pub fn describe() -> &'static str {
    "geometry module"
}
examples/28_modules/src/geometry/area.rs
//! area 子模块:面积计算。

/// 矩形面积。
pub fn rectangle(width: f64, height: f64) -> f64 {
    width * height
}

/// 圆面积。
pub fn circle(radius: f64) -> f64 {
    std::f64::consts::PI * radius * radius
}
examples/28_modules/Cargo.toml
[package]
name = "rt_28_modules"
version.workspace = true
edition.workspace = true
publish.workspace = true