如何从另一个文件导入模块到 Rust:从新手到自信用户
\n\n您是否曾经在编写 Rust 代码时,突然发现您的 main.rs 变成了一个 500 行的庞然大物?似曾相识吗?或者,您可能刚开始学习 Rust,并希望了解如何正确组织代码,将其拆分成多个文件。"How can I include a module from another file from the same project?" 这个问题是 Stack Overflow 上最热门的问题之一,这并非没有原因。Rust 的模块系统既强大又……对新手来说有点不太直观。
在本文中,我们将从头到尾详细讲解:如何创建模块,如何导入它,有哪些陷阱以及如何避免踩坑。我们开始吧!
\n\n为什么 Rust 中的模块不仅仅是 "include"?
\n\n如果您是从 Python 或 JavaScript 转过来的,您可能习惯了 import 或 require。在 Rust 中,情况略有不同。这里没有神奇的“自动获取文件并使用”。相反,Rust 使用声明式模块系统。您必须明确告诉编译器:“嘿,这个文件是我项目的一部分,它的名字是这么叫的”。
需要记住的基本规则是:每个文件都是一个模块,但并非每个模块都是一个文件。听起来像谜语,对吧?我们现在就来弄清楚。
\n\n项目结构:从何开始
\n\n假设您有一个具有以下结构的项目:
\n\nmy_project/\n├── Cargo.toml\n├── src/\n│ ├── main.rs\n│ ├── greetings.rs\n│ └── utils/\n│ ├── mod.rs\n│ └── helpers.rs\n\n这里,greetings.rs 是一个简单的模块,而 utils/ 是一个包含模块的文件夹。让我们学习如何导入它们。
方法 1:导入简单的文件模块
\n\n这是最基本的情况。您有一个包含函数的 greetings.rs:
// greetings.rs\npub fn say_hello() {\n println!("来自 greetings 模块的问候!");\n}\n\n要在 main.rs 中使用这个模块,您需要做两件事:
- \n
- 声明模块,使用关键字
mod\n - 导入所需的元素,使用
use\n
// main.rs\nmod greetings; // 声明模块\n\nuse greetings::say_hello; // 导入函数\n\nfn main() {\n say_hello(); // 使用它\n}\n\n就是这样!Rust 会自动在与 main.rs 相同的文件夹中查找 greetings.rs 文件。如果找到该文件,模块就会被导入。
重要提示: 函数 say_hello 被标记为 pub。如果忘记写 pub,编译器会提示该函数是私有的,无法从外部访问。这是新手最常见的错误之一。
方法 2:文件夹中的模块 (mod.rs 或 lib.rs)
\n\n当您的项目规模扩大时,将模块分组到文件夹中会很方便。为此,需要在文件夹内使用 mod.rs 文件。它充当模块的“入口点”。
创建文件夹 utils/,并在其中创建 mod.rs:
// utils/mod.rs\npub mod helpers; // 声明嵌套模块\n\n现在创建 helpers.rs:
// utils/helpers.rs\npub fn do_something() {\n println!("做一些有用的事情");\n}\n\n在 main.rs 中这样导入:
// main.rs\nmod utils; // 声明 utils 模块(查找 utils/mod.rs)\n\nuse utils::helpers::do_something;\n\nfn main() {\n do_something();\n}\n\n请注意:mod utils; 告诉 Rust 查找 utils/mod.rs 或 utils.rs。如果找到 mod.rs——很好,如果找到 utils.rs——也可以。但不能同时存在这两个文件——编译器会混淆。