1. 使用 use 声明简化路径

知识点概括

  • use 关键字允许你为模块成员创建一个更短的、方便访问的别名。
  • 它可以用于导入单个函数、结构体或整个模块。

示例代码

假设我们有如下目录结构:

复制代码
src
├── main.rs
└── network
    └── http.rs

network/http.rs 中定义了一个公共函数 get

rust 复制代码
// src/network/http.rs
pub fn get() {
    println!("Performing an HTTP GET request.");
}

为了在 main.rs 中调用这个函数,我们可以直接使用完整路径:

rust 复制代码
// src/main.rs
mod network;

fn main() {
    network::http::get();
}

但这样写比较冗长。我们可以使用 use 来简化:

rust 复制代码
// src/main.rs
mod network;
use network::http::get;

fn main() {
    get(); // 现在可以直接调用 get 函数
}

注意事项

  • 使用 use 导入时,确保导入的项是公共的(即带有 pub 关键字)。
  • 可以通过 as 关键字给导入的项起别名,例如 use network::http::get as http_get;

2. 超级模式(Super)和当前模式(Self)

知识点概括

  • superself 是路径前缀,分别指代当前模块的父模块和当前模块本身。
  • 这些前缀有助于明确地引用模块成员,尤其是在存在命名冲突的情况下。

示例代码

考虑以下目录结构:

复制代码
src
├── main.rs
└── my_mod.rs

my_mod.rs 中定义两个函数:

rust 复制代码
// src/my_mod.rs
fn function() {
    println!("Called `function()`");
}

pub fn call_function() {
    // 使用 `self` 明确引用当前模块中的 `function`
    self::function();
    // 或者直接调用(在同一个模块中)
    function();
}

如果想要从 main.rs 中调用 call_function 并且希望它也能调用 my_mod 中的 function,你可以这样做:

rust 复制代码
// src/main.rs
mod my_mod;
use my_mod::call_function;

fn function() {
    println!("Called `main::function()`");
}

fn main() {
    call_function(); // 调用 `my_mod::call_function`
    
    // 如果需要区分 `main` 和 `my_mod` 中的同名函数,可以使用 `super`
    super::function(); // 调用 `main` 中的 `function`
}

注意事项

  • 使用 superself 可以帮助避免命名冲突,并提高代码的可读性。
  • 在大型项目中合理使用这些关键字可以使代码结构更加清晰。

3. 模块与文件系统的对应关系

知识点概括

  • Rust 的模块系统紧密关联于文件系统布局。默认情况下,Rust 会根据文件和目录结构来解析模块。
  • 使用 mod.rs 文件是一种传统方式,但现在也可以直接使用文件夹名称作为模块名。

示例代码

考虑以下目录结构:

复制代码
src
├── main.rs
└── utils
    ├── mod.rs // 或者直接命名为 utils.rs
    └── string_utils.rs

utils/string_utils.rs 中定义一个函数:

rust 复制代码
// src/utils/string_utils.rs
pub fn to_uppercase(s: &str) -> String {
    s.to_uppercase()
}

然后,在 utils/mod.rs 中声明子模块:

rust 复制代码
// src/utils/mod.rs
pub mod string_utils;

最后,在 main.rs 中使用:

rust 复制代码
// src/main.rs
mod utils;
use utils::string_utils::to_uppercase;

fn main() {
    let result = to_uppercase("hello world");
    println!("{}", result);
}

注意事项

  • 如果不使用 mod.rs,可以直接将模块文件命名为与目录相同的名称(如 utils.rs),并省略 mod.rs 文件。
  • 确保每个模块文件都有正确的权限设置(如 pub),以便外部可以正确访问它们的成员。