type
Post
date
Nov 2, 2025
slug
Rust/notebook/7
summary
学习下 Rust 圣经,记录笔记
status
Published
tags
Rust
category
技术茶点
icon
password
😀
本章讲解 Rust 模块系统——如何通过包、crate、模块、路径和作用域,来组织、封装和管理大型项目的代码结构,使代码清晰、可维护且安全。

7.使用包、crate和模块

7.1.包和crate

一个 package 可以包含多个 crate,而 crate 是 Rust 编译的最小单位。
概念
说明
举例
crate(箱)
Rust 编译的最小单位。分两类:① 库 crate 提供功能模块;② 二进制 crate 可执行。
main.rs 是二进制 crate;lib.rs 是库 crate。
package(包)
由 Cargo 管理的项目单元,里面可以有 1 个库 crate 和 多个二进制 crate。
cargo new myapp 就建了一个 package。
crate root(根)
每个 crate 的起点文件,告诉编译器从哪儿开始编译。
src/main.rssrc/lib.rs

7.2.定义模块来控制作用域与私有性

术语
含义
关键点
模块(module)
mod 声明,用于将代码按功能分组。
模块让代码结构清晰、便于组织和导航。 (kaisery.github.io)
模块树(module tree)
所有模块和子模块组成的层次结构,从 crate 根开始。
crate 根(如 src/lib.rssrc/main.rs)是整个结构的起点。 (kaisery.github.io)
路径(paths)
指向模块中项(函数、结构体等)的方式,比如 crate::front_of_house::hosting::add_to_waitlist
用于在代码中引用模块内、模块间的项。 (kaisery.github.io)
私有性 vs 公用性(privacy / pub)
默认所有模块内的项对其父模块是私有的,要使模块或项被外部访问必须使用 pub
- 用 pub mod 声明公用模块 - 在模块内部,若要让结构体、函数等可外部访问,也要用 pub。 (kaisery.github.io)
引入(use)
use 将路径引入当前作用域,以简化访问。
通过 use 可以缩短冗长路径,提升代码可读性。 (kaisery.github.io)

7.3.引用模块树中项的路径

概念
含义
关键点
路径(Path)
用于在模块树中定位项(函数、结构体、模块等)的方法。 (doc.rust-lang.org)
路径由一个或多个标识符通过 :: 连接。 (doc.rust-lang.org)
绝对路径(Absolute path)
从 crate 根开始的完整路径。 (doc.rust-lang.org)
当前 crate 中以 crate:: 开头;引用外部 crate 以 crate 名称 开头。
相对路径(Relative path)
从当前模块出发的路径。可使用 selfsuper 或模块标识符。 (Rustの日本語ドキュメント/Japanese Docs for Rust)
例如:super::some_module::some_item 表示从父模块开始构建相对路径。
使用场景 & 优劣
决定用绝对路径或相对路径取决于模块的组织与项目未来可能的重构。 (doc.rust-lang.org)
如果模块可能被移动,使用绝对路径更稳定;如果模块跟调用者经常一起移动,使用相对路径更便捷。
可见性影响
虽然路径写对了,但如果路径中某一模块或项不可见(私人/private),编译会报错。 (doc.rust-lang.org)
即:用 pub 使模块或项公开,才能让外部通过路径访问。

7.4.使用use关键字将路径引入作用域

 
概念
含义
关键点
use 关键字
用于在当前作用域创建一个路径的快捷方式。(doc.rust-lang.org)
写一次 use crate::foo::bar; 后,就可在该作用域直接使用 bar,省掉每次写完整路径。(doc.rust-lang.org)
作用域限制
use 引入的名字只在其声明的作用域内有效。(doc.rust-lang.org)
如果在父模块写了 use,但在子模块使用,就可能 “找不到” 名称,因为子模块是一个新的作用域。(doc.rust-lang.org)
惯用法(Idiomatic way)
- 通常 use 引入模块路径(如 use crate::front_of_house::hosting;),然后调用 hosting::…。 (rust-book.cs.brown.edu) - 对于结构体、枚举直接引入具体类型,如 use std::collections::HashMap;。(rust-book.cs.brown.edu)
这样既避免每次写冗长路径,也保留一定的模块前缀以提示来源。
别名 as
可以用 as 给引入的名称起别名,解决命名冲突。(doc.rust-lang.org)
例如 use std::io::Result as IoResult; 用于区分 std::fmt::Resultstd::io::Result。(rust-book.cs.brown.edu)
重新导出 pub use
如果希望将某个引入的名称公开给外部模块使用,可以使用 pub use。(doc.rust-lang.org)
例如库内部结构复杂,但对外暴露更简洁路径,使用 pub use 让外部用更简路径访问。

7.5.将模块拆分成多个文件

概念
含义
关键点
模块拆文件
当模块体积变大时,可以把一个模块的定义从当前文件移到单独的 .rs 文件中。 (doc.rust-lang.org)
在 crate 根文件(如 src/lib.rssrc/main.rs)用 mod module_name; 声明模块。模块的定义代码放在 src/module_name.rs。 (doc.bccnsoft.com)
保留模块树结构
虽然文件被拆开,但模块的嵌套结构(module tree)不会改变。 (doc.rust-lang.org)
调用模块路径的方式不变,比如 crate::front_of_house::hosting::add_to_waitlist 仍然有效。 (doc.rust-lang.org)
文件名与目录约定
模块 front_of_house 的代码可以位于 src/front_of_house.rs;如果模块有子模块,还可用 src/front_of_house/mod.rs 或新版推荐 src/front_of_house.rs + src/front_of_house/submodule.rs。 (Rust Internals)
Rust 2018 版以后倾向于避免大量 mod.rs 文件,用更清晰的目录和文件结构。 (Rust Internals)
为何拆分
主要是为了代码可维护性:当模块越来越大、逻辑越来越复杂时,把它拆到单独文件,让项目结构更清晰、更利于导航。 (doc.bccnsoft.com)
虽然拆文件不会改变编译单元(crate)或模块可见性,但更易管理。 (doc.rust-lang.org)
 
《Rust 程序设计语言》(8/22)《Rust 程序设计语言》(6/22)
Loading...