清晰解释铁锈的模块系统

2020-07-19 22:54:09

Rust的模块系统出人意料地令人困惑,给初学者带来了很多挫败感。

在这篇文章中,我将用实际的例子解释模块系统,这样你就可以清楚地了解它是如何工作的,并可以立即开始在你的项目中应用它。

由于Rust的模块系统非常独特,我请求读者以开放的心态阅读这篇文章,不要将其与其他语言中模块的工作方式进行比较。

My_project├──cargo.toml└─┬src├──main.rs├──config.rs├─┬Routs│├──│└──_route.rs└─┬_route.rs└──Models User_Model.rs。

这3个例子应该足以解释Rust的模块系统是如何工作的。

每个人都会犯的第一个错误是因为我们有config.rs、Health_route.rs等文件,我们认为这些文件是模块,我们可以从其他文件导入它们。

下面是我们看到的(文件系统树)和编译器看到的(模块树):

令人惊讶的是,编译器只看到板条箱模块,这是我们的main.rs文件。这是因为我们需要在Rust中显式构建模块树-文件系统树到模块树之间没有隐式映射。

我们需要在Rust中显式构建模块树,没有隐式映射到文件系统。

要将文件添加到模块树中,我们需要使用mod关键字将该文件声明为子模块。下一件让人困惑的事情是,您会认为我们将文件声明为同一文件中的模块。但是我们需要在另一个文件中声明这一点!因为我们在模块树中只有main.rs,所以让我们将config.rs声明为main.rs中的子模块。

My_project├──cargo.toml└─┬src├──main.rs└──my_mode.rsormy_project├──cargo.toml└─┬src├──main.rs└─┬my_module└──mod.rs。

由于main.rs和config.rs位于同一目录中,因此我们按如下方式声明config模块:

我们已经成功声明了配置模块!但这还不足以调用config.rs内的print_config函数。默认情况下,Rust中的几乎所有内容都是私有的,我们需要使用关键字pub将函数设置为公共的:

现在,这起作用了。我们已经成功地调用了在不同文件中定义的函数!

如前所述,我们只能对同一目录中的my_module e.rs或my_module/mod.rs使用mod关键字。

因此,为了从main.rs调用routes/Health_route.rs内的函数,我们需要执行以下操作:

My_├──货物.toml└─┬src├──main.rs├──config.rs├─┬Routs+│├──mod.rs│├──│└──_route.rs└─┬Models└──User_Model.rs。

让我们进行与前面相同的更改-声明子模块、使函数成为公共函数并添加mod.rs文件。

My_├──货物.toml└─┬src├──main.rs├──config.rs├─┬Routs│├──mod.rs│├──│└──_route.rs└─┬User_route.rs├──Model.rs└──User_Model.rs。

等等,我们还没有真正从print_user_route调用print_user_model!到目前为止,我们只从main.rs调用了其他模块中定义的函数,如何从其他文件调用这些函数呢?

如果我们查看我们的模块树,则print_user_model函数位于crate::model::user_model路径中。因此,为了在不是main.rs的文件中使用模块,我们应该考虑到达模块树中该模块所需的路径。

我们已经成功地从非main.rs的文件中调用了在文件中定义的函数。

如果我们的文件组织是多个目录深度的,则完全限定名会变得太长。比方说,无论出于什么原因,我们都想从print_user_route调用print_Health_route。它们分别位于路径CARATE::ROUES::Health_ROUTE和CARATE::ROUES::USER_ROUTE下。

我们可以使用完全限定名crate::routes::health_route::print_health_route()来调用它,但是我们也可以使用相对路径SUPERR::HANTONALY_ROUTE::PRINT_HANTONALY_ROUTE();。请注意,我们已经使用SUPER来引用父作用域。

在上面的示例中使用完全限定名甚至相对名称会很繁琐。为了缩短名称,我们可以使用USE关键字将路径绑定到新名称或别名。

添加到Cargo.toml的依赖项对项目内的所有模块全局可用。使用依赖项不需要显式导入或声明任何内容。

例如,假设我们将兰特板条箱添加到项目中。我们可以在代码中直接使用它,如下所示:

模块系统是显式的-与文件系统没有1:1的映射。

我们需要显式地将函数、结构等声明为公共函数,以便可以在其他模块中使用它们。

谢谢你的阅读!请随时在推特上关注我,获得更多这样的帖子:)。

在Github、Twitter或LinkedIn上找到我。请随时通过sheshbabu[at]gmail.com与我联系