rust 模块

一、模块系统的基础

1. 模块的定义

模块是 Rust 中组织代码的基本单元。通过模块,你可以将代码划分为逻辑单元,控制可见性,避免命名冲突。

  • 定义模块

    mod my_module {
        // 模块内容
    }
    
  • 模块的作用域
    模块内的项(函数、结构体、枚举等)默认是私有的,只能在模块内部访问。使用 pub 关键字可以公开这些项。

2. 模块的可见性

  • 私有(默认):只能在模块内部访问。
  • 公开(pub:可以在模块外部访问。
  • 受限公开
    • pub(crate):在整个 crate 内可见。
    • pub(super):在父模块中可见。
    • pub(in path):在指定路径下可见。

示例:

mod outer {
    pub mod inner {
        pub(crate) fn foo() {} // 整个 crate 可见
        pub(super) fn bar() {} // 父模块(outer)可见
        pub(in crate::outer) fn baz() {} // 仅在 outer 模块中可见
    }
}

二、模块与文件系统

Rust 的模块系统与文件系统紧密相关。模块可以定义在单个文件中,也可以拆分到多个文件中。

1. 模块的文件映射

  • 规则

    • 当你在一个文件中声明 mod module_name; 时,Rust 会查找:
      • 同级目录下的 module_name.rs 文件,或
      • 同级目录下的 module_name/mod.rs 文件。
  • 示例

    my_crate/
    ├── Cargo.toml
    └── src/
        ├── main.rs
        ├── network.rs      // 对应 `mod network;`
        └── client/
            ├── mod.rs      // 对应 `mod client;` 中的内容
            └── api.rs      // 子模块可通过 `mod api;` 引入
    

2. 文件内容示例

  • src/main.rs:

    mod network; // 引入 network.rs 或 network/mod.rs
    
    fn main() {
        network::connect();
    }
    
  • src/network.rs:

    pub mod client; // 引入 client.rs 或 client/mod.rs
    
    pub fn connect() {}
    
  • src/client/mod.rs:

    pub mod api; // 引入 api.rs
    
    pub fn connect() {}
    
  • src/client/api.rs:

    pub fn connect() {}
    

三、路径与 use 关键字

1. 路径类型

  • 绝对路径:从 crate 根开始,以 crate:: 或第三方 crate 名开头。
    crate::network::client::connect();
    
  • 相对路径:从当前模块开始,用 self(当前模块)、super(父模块)或模块名。
    self::client::connect();
    super::network::connect();
    

2. 使用 use 引入路径

use 关键字用于将路径引入当前作用域,避免重复写完整路径。

  • 基本用法

    use crate::network::client;
    
    fn main() {
        client::connect();
    }
    
  • 重命名

    use std::fmt::Result as FmtResult;
    
  • 合并引入

    use std::{cmp::Ordering, io};
    
  • 通配符引入

    use std::collections::*; // 引入所有项
    

3. 再导出(Re-export)

使用 pub use 将内部项公开到当前作用域,方便外部调用。

示例:

// 在 network/mod.rs 中
pub use self::client::connect; // 外部可直接通过 network::connect 访问

四、模块的高级用法

1. 测试模块

使用 #[cfg(test)] 标记测试模块,测试代码仅在测试时编译。

示例:

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}

2. 全局可见的 Prelude

lib.rsmain.rs 中定义一个 prelude 模块,导出常用项。

示例:

pub mod prelude {
    pub use crate::network::client::Client;
    pub use crate::types::*;
}

3. 处理循环依赖

避免循环依赖,或使用 pub(crate) 限制可见性,或重构代码结构。


五、模块的最佳实践

  1. 按功能划分模块:将相关的功能放在同一个模块中。
  2. 避免过深的嵌套:模块嵌套不宜过深,通常不超过 3 层。
  3. 使用 pub use 简化接口:将内部模块的常用项再导出,方便外部调用。
  4. 合理使用可见性:避免过度公开,保持模块的封装性。

六、常见问题与解决方案

1. 找不到模块

  • 原因:文件路径与 mod 声明不匹配。
  • 解决:检查文件路径和 mod 声明是否一致。

2. 私有项无法访问

  • 原因:未使用 pub 关键字。
  • 解决:检查是否遗漏 pub

3. 循环依赖

  • 原因:模块之间相互引用。
  • 解决:重构代码,或将公共部分提取到新模块。

七、完整示例

目录结构

my_app/
├── Cargo.toml
└── src/
    ├── main.rs
    ├── lib.rs
    ├── utils/
    │   ├── mod.rs
    │   └── math.rs
    └── models/
        ├── mod.rs
        └── user.rs

代码示例

  • src/lib.rs:

    pub mod utils;
    pub mod models;
    
  • src/utils/mod.rs:

    pub mod math;
    
  • src/utils/math.rs:

    pub fn add(a: i32, b: i32) -> i32 {
        a + b
    }
    
  • src/models/mod.rs:

    pub mod user;
    
  • src/models/user.rs:

    pub struct User {
        pub name: String,
    }
    
  • src/main.rs:

    use my_app::utils::math;
    use my_app::models::user::User;
    
    fn main() {
        println!("2 + 3 = {}", math::add(2, 3));
    
        let user = User { name: String::from("Alice") };
        println!("User name: {}", user.name);
    }
    

Read more

MongoDB

1. 安装 MongoDB 1.1 在 Windows 上安装 1. 下载 MongoDB: * 访问 MongoDB 官方网站 下载适合 Windows 的安装包。 2. 安装 MongoDB: * 运行下载的安装程序,按照提示完成安装。 3. 设置环境变量: * 将 MongoDB 的 bin 目录添加到系统的环境变量中,以便在命令行中使用 mongo 和 mongod 命令。 4. 创建数据目录: * 默认情况下,MongoDB 会在 C:\data\db 目录下存储数据。你可以手动创建这个目录,或者在启动 MongoDB 时指定其他目录。 1.2 在

By amm

© 2025 路不易All rights reserved.

备案号:黔ICP备2025043243号-1 | 公安备案图标 贵公网安备52052402000220号