Day 18: 模块系统
1. 模块基础概念
Section titled “1. 模块基础概念”Rust的模块系统用于组织代码,提供了代码封装和作用域控制两种主要功能。通过模块可以:
- 将相关代码组织在一起
- 控制哪些内容对外可见(公有/私有)
- 实现代码复用和命名空间管理
2. 定义模块
Section titled “2. 定义模块”使用 mod 关键字定义模块:
// 定义模块mod utils { // 模块内可以定义函数、结构体、枚举等 pub fn add(a: i32, b: i32) -> i32 { a + b }
pub fn multiply(a: i32, b: i32) -> i32 { a * b }
// 私有函数,外部无法访问 fn helper() { println!("helper 函数"); }
pub mod nested { pub fn greet() { println!("Hello!"); } }}
fn main() { // 使用模块中的函数 println!("3 + 5 = {}", utils::add(3, 5)); println!("3 * 5 = {}", utils::multiply(3, 5));
// 访问嵌套模块 utils::nested::greet();}3. pub 关键字:控制可见性
Section titled “3. pub 关键字:控制可见性”Rust默认所有内容是私有的。使用 pub 关键字使内容对外可见:
mod my_module { // 私有项 fn private_function() { println!("私有函数"); }
// 公有项 pub fn public_function() { println!("公有函数"); }
// 仅对模块内可见(但对子模块可见) pub(crate) fn crate_public_function() { println!(" crate 内可见"); }
// 仅对父模块可见 pub(super) fn super_public_function() { println!("父模块可见"); }
// 结构体字段的可见性 pub struct Config { pub api_key: String, // 公开字段 internal: String, // 私有字段 }
impl Config { pub fn new(api_key: &str) -> Self { Config { api_key: api_key.to_string(), internal: String::new(), } } }}
fn main() { my_module::public_function();
let config = my_module::Config::new("secret"); println!("API Key: {}", config.api_key); // println!("{}", config.internal); // 编译错误!私有字段}4. use 语句:导入模块
Section titled “4. use 语句:导入模块”使用 use 语句将模块引入当前作用域,避免重复写完整路径:
mod network { pub mod http { pub fn get(url: &str) { println!("GET {}", url); }
pub fn post(url: &str, body: &str) { println!("POST {}: {}", url, body); } }
pub mod json { pub fn parse(s: &str) { println!("解析 JSON: {}", s); }
pub fn stringify(obj: &str) { println!("转 JSON: {}", obj); } }}
// 完整路径fn main() { network::http::get("https://api.example.com"); network::json::parse("{}");
// 使用 use 简化 use network::http;
http::get("https://api.example.com"); http::post("https://api.example.com", "{}");
// 使用 as 起别名 use network::json::parse as parse_json; use network::json::stringify as stringify_json;
parse_json("{\"name\": \"Rust\"}"); stringify_json("object");}5. re-export(重导出)
Section titled “5. re-export(重导出)”使用 pub use 可以在当前位置导出子模块的项:
mod outer { pub mod inner { pub fn function() { println!("inner::function"); } }
// 将 inner::function 重导出到 outer 模块级别 pub use inner::function;}
fn main() { // 直接从 outer 访问 outer::function(); // 等价于 outer::inner::function()}6. 文件系统与模块映射
Section titled “6. 文件系统与模块映射”Rust模块与文件系统一一对应。文件就是模块,目录通过 mod.rs 定义模块:
// src/main.rs 或 src/lib.rsmod restaurant; // 引入 restaurant.rs 或 restaurant/mod.rspub mod front_of_house { pub mod hosting { pub fn add_to_waitlist() { println!("已添加到等待列表"); }
pub fn seat_at_table() { println!("已安排座位"); } }
pub mod menu { pub struct MenuItem { pub name: String, pub price: f64, }
impl MenuItem { pub fn new(name: &str, price: f64) -> Self { MenuItem { name: name.to_string(), price, } } } }}
// 公开的 APIpub use front_of_house::hosting;
pub fn eat_at_restaurant() { // 使用绝对路径 crate::front_of_house::hosting::add_to_waitlist();
// 使用相对路径 front_of_house::hosting::seat_at_table();
// 通过 pub use 重导出的路径 hosting::add_to_waitlist();
// 点餐 let menu_item = front_of_house::menu::MenuItem::new("汉堡", 25.0); println!("点了 {},价格 {} 元", menu_item.name, menu_item.price);}7. self 与 super
Section titled “7. self 与 super”使用 self 引用当前模块,super 引用父模块:
mod outer_module { pub fn outer_function() { println!("outer function"); }
mod inner_module { pub fn inner_function() { println!("inner function"); }
pub fn call_outer() { // 调用父模块的函数 super::outer_function(); }
pub fn call_self() { // 调用当前模块的其他函数 self::inner_function(); }
pub fn call_parent_method() { super::outer_function(); } }
pub fn public_entry() { inner_module::call_outer(); inner_module::call_self(); }}
fn main() { outer_module::public_entry();}今天我们学习了Rust模块系统:
- 模块定义:
mod关键字定义模块,模块内可包含函数、结构体、枚举等 - 可见性控制:
pub关键字控制公有/私有,pub(crate)、pub(super)限制可见范围 - use语句:
use导入模块简化路径,as起别名,pub use重导出 - 文件系统映射:文件对应模块,
mod.rs定义目录模块 - self/super:
self引用当前模块,super引用父模块
良好的模块化设计是构建大型Rust项目的基础。明天我们将学习包管理器 Cargo 的使用方法。