crate 根

在 Rust 中,crate 是一个主要的组织单位,可以是一个库或一个可执行文件。crate 根是指 crate 的根模块,它是 crate 中所有其他模块的父模块。

参考资料使用包、Crate和模块管理不断增长的项目

简单的来说 crate 就是 包,或者定义包和查找包的入口

一般项目有两个这样的入口,一个是src/main.rs 二进制(可执行)crate,一个是src/lib.rs 库crate

如果 你的项目是一个库项目那么crate 就写在 src/lib.rs ,库里面所有mod信息起始位置都要在这里里面定义

如果 你的项目是一个二进制 可执行文件的项目 那么crate就写在 src/main.rs 里面,所有的mod定义的起始也是协在这里面。

当然你的项目既可以是二进制项目也可以是库项目,两个地方都可以定义,使用方式随便。

如果你的项目要做多个二进制文件,那么你的文件就放在src/bin 目录,文件名称不重复,如果你项目还会使用src/main.rs,bin目录下面不能出现和项目名称相同的文件,不使用的话就无所谓了,这个是你构建二进制时的可执行文件名称。那么你的项目就有多个二进制crate了,当然src/main.rs 依然可以写,不冲突,构建处理的时候 二进制文件名称就是项目名称

以下是关于 crate 根的一些详细信息:

库 crate 的 crate 根

对于库 crate,crate 根是 src/lib.rs 文件。这个文件包含了 crate 的根模块,所有的公共(public)类型、函数、模块等都应该在这个文件中声明或者导出。

例如,在 src/lib.rs 中,您可以定义模块和导出它们:

// src/lib.rs

// 定义一个模块
mod my_module {
    // 模块内容
    pub fn my_function() {
        println!("Hello from my_module!");
    }
}

// 导出模块,使其在 crate 外可见
pub use my_module::my_function;

可执行 crate 的 crate 根

对于可执行 crate,crate 根是 src/main.rs 文件。这个文件通常包含 main 函数,是程序的入口点。

例如,在 src/main.rs 中,您可以引用其他模块:

// src/main.rs

// 引入其他模块
mod my_module;

fn main() {
    // 使用 my_module 中的函数
    my_module::my_function();
}

注意事项
在 Rust 中,每个 crate 都有一个 crate 根,无论是库 crate 还是可执行 crate。
crate 根是定义公共 API 的地方,您可以从这里导出(通过 pub 关键字)您希望其他代码使用的类型和函数。
在 crate 根内部,您可以定义模块,并且可以决定哪些模块或模块内的项应该对外公开。
通过在 crate 根文件中组织代码,您可以控制 crate 的结构和公共接口,同时保持内部实现细节的封装。

示例项目

以下是一个综合示例,展示了如何在 Rust 项目中使用 use、as、crate 关键字,以及如何通过相对路径和绝对路径引用模块。这个示例将包含一个库 crate 和一个可执行 crate,它们都位于同一个项目目录中。

项目结构

\---src
    |   lib.rs
    |   main.rs
    |   utils.rs
    |
    \---math
            operations.rs

lib.rs

// src/lib.rs
pub mod utils;

//导出引入`utils`模块的`greet`函数,以便在其他地方使用
pub use utils::greet;

// 模块`math`的声明,包含数学相关功能
pub mod math {
    // 子模块`operations`的声明,包含数学运算相关功能
    pub mod operations;
}

utils.rs

// src/utils.rs

// 定义一个公共函数,可以在其他模块中使用
pub fn greet(name: &str) {
    println!("Hello, {}!", name);
}

math/operations.rs

// src/math/operations.rs

// 定义一个公共函数,可以在其他模块中使用
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

// 在库 crate 的根模块中使用绝对路径引用 operations 模块
pub fn lib_add_example() {
    let result = crate::math::operations::add(5, 3);
    println!("Result from lib_add_example: {}", result);
}

main.rs

// src/main.rs

// 引入库 crate 的根模块
mod utils;
use RustMod0;
// 主函数,程序的入口点
fn main() {
    // 使用别名导入模块中的函数,以简化调用
    use RustMod0::math::operations::add;
    // 调用 crate 根模块下的函数,向其传递参数 "123"
    crate::RustMod0::greet("123");
    // 调用 utils 模块下的函数,向其传递参数 "123"
    crate::RustMod0::utils::greet("123");
    // 调用本地 utils 模块下的函数,向其传递参数 "123"
    utils::greet("123");

    // 调用导入的 add 函数并传入参数 10 和 20,将返回值存储在 result 变量中
    let result = add(10, 20);
    // 打印调用 add 函数的结果
    println!("Result from add: {}", result);

    // 使用别名重新导入同一个函数,以演示命名冲突的解决
    use RustMod0::math::operations::add as custom_add;
    // 调用重新命名的 add 函数并传入参数 30 和 40,将返回值存储在 custom_result 变量中
    let custom_result = custom_add(30, 40);
    // 打印调用 custom_add 函数的结果
    println!("Result from custom_add: {}", custom_result);

    // 调用 lib_add_example 函数,该函数可能在演示或测试其他功能
    RustMod0::math::operations::lib_add_example();
}

在这个示例中,我们展示了以下概念:

pub use:在 lib.rs 中使用 pub use 来公开 utils 模块中的 greet 函数,使其可以从外部访问。
相对路径:在 main.rs 中使用相对路径 utils::greet("123"); 调用本地的方法
绝对路径:在 main.rs 中使用 crate:: 前缀来引用 crate 根级别的项比掉lib库根里面的项。
use:在 main.rs 中使用 use 关键字来简化对 operations 模块的引用。
as:在 main.rs 中使用 as 关键字来重命名引入的 add 函数为 custom_add。
通过这个示例,你可以看到如何在 Rust 中组织代码,使用不同的路径和关键字来引用模块中的项