在Rust中,mod.rs文件的目的是什么?

Lia*_*all 13 module rust

在我见过的一些Rust项目中(即pczarn/rustboot),mod.rs无论出于何种原因,我都在目录中看过文件.我无法找到关于此的文档,我在许多其他Rust项目中都看到了它.mod.rs文件的目的是什么,我什么时候应该使用它?

Rom*_*ent 81

理解模块很重要,但我发现大多数文档常常让您在这个问题上摸不着头脑。

\n

来自Python还是Javascript

\n

粗略地说,mod.rs有点像__init__.pypython 或index.jsjavascript。\n但只是有点。这在 Rust 中有点复杂。

\n

铁锈是不同的

\n

文件夹还不能立即用作 Rust 中的模块。

\n

您必须添加一个mod.rs在文件夹中命名的文件才能公开一个以该文件夹命名的新模块。\n其中的代码mod.rs是该模块的内容。\n该文件夹中的所有其他文件可能会作为子模块公开(更多内容请参见下文) )。

\n

等等,还有一个办法

\n

mod.rs您可以添加与文件夹<folder_name>.rs同级命名的文件,而不是在文件夹中添加文件。

\n

正如 MarkusToman 在评论中指出的,这是自 rustc 1.30 以来的首选方式。

\n

来自Rust 参考

\n
\n

注意:在 rustc 1.30 之前,使用 mod.rs 文件是加载具有嵌套子项的模块的方法。鼓励使用新的\n命名约定,因为它更加一致,并避免在项目中存在许多\n名为 mod.rs 的文件。

\n
\n

完整示例

\n
src\n    utils\n        bar.rs\n        foo.rs\n    main.rs\n
Run Code Online (Sandbox Code Playgroud)\n

此时,编译器不知道src/utils/foo.rsand src/utils/bar.rs

\n

首先,你必须揭露src/utils/。如上所示,您有 2 个选择:

\n
    \n
  • 添加文件:src/utils/mod.rs
  • \n
  • 添加文件src/utils.rs(名称与文件夹完全相同,不带扩展名)
  • \n
\n

现在,相对于 src 文件夹(也称为 crate 级别),有一个名为 的模块utils可用。

\n

其次,您必须公开文件src/utils/foo.rssrc/utils/bar.rs.

\n

为此,模块必须声明 2 个以这些文件命名的新子模块。\n因此(或)utils的内容应为:src/utils/mod.rssrc/utils.rs

\n
src\n    utils\n        bar.rs\n        foo.rs\n    main.rs\n
Run Code Online (Sandbox Code Playgroud)\n

现在,这两个文件中公开的任何内容都可以在其他模块中使用!

\n

您可以在 中写下以下内容src/main.rs

\n
pub mod bar;\npub mod foo;\n
Run Code Online (Sandbox Code Playgroud)\n

结果文件结构

\n

选项 1 \xe2\x80\xa2mod.rs(旧方法):

\n
src\n    utils\n        bar.rs\n        foo.rs\n        mod.rs\n    main.rs\n
Run Code Online (Sandbox Code Playgroud)\n

选项 2 \xe2\x80\xa2<folder_name>.rs(首选方式):

\n
src\n    utils\n        bar.rs\n        foo.rs\n    utils.rs\n    main.rs\n
Run Code Online (Sandbox Code Playgroud)\n
\n
\n
\n

有关模块如何工作的更多高级详细信息

\n
\n

这仍然是表面解释,你的下一个目的地是官方文档 \xe2\x80\x8d

\n
\n

还有第三种声明模块的方法(核心语言):

\n
mod utils;\nuse utils::{foo, bar};\n
Run Code Online (Sandbox Code Playgroud)\n

但也可以只写mod utils;。\n在这种情况下,如上所示,Rust 知道搜索src/utils.rssrc/utils/mod.rs

\n

请注意,当您尝试在文件中(例如src/main.rs)使用模块时,\n您可以通过以下方式引用它:

\n
    \n
  • 从内部:src/main.rs\n
      \n
    • mod module { ... }
    • \n
    \n
  • \n
  • 来自内部的嵌套模块:src/main.rs\n
      \n
    • mod module { pub mod sub_module { ... } }
    • \n
    \n
  • \n
  • 来自 sybling 文件:src/*.rs
  • \n
  • mod.rssybling 文件夹中的文件:src/*/mod.rs
  • \n
  • (以及上述的无限递归组合)
  • \n
\n
\n

包含的文件或文件夹mod.rs不会成为模块。
\n相反,Rust 语言允许您使用文件层次结构来组织模块(一种语言功能)。

\n

真正有趣的是你可以自由地将所有方法混合在一起。

\n

例如,您可能认为不能直接src/utils/foo.rs引用main.rs.
\n但你可以:

\n
src\n    utils\n        bar.rs\n        foo.rs\n        mod.rs\n    main.rs\n
Run Code Online (Sandbox Code Playgroud)\n

重要笔记

\n
    \n
  • 文件中声明的模块始终优先(因为实际上您永远不需要搜索文件层次结构)
  • \n
  • 您不能使用其他两种方法来引用同一模块
  • \n
\n

例如,同时具有src/utils.rssrc/utils/mod.rs将会在编译时引发以下错误:

\n
src\n    utils\n        bar.rs\n        foo.rs\n    utils.rs\n    main.rs\n
Run Code Online (Sandbox Code Playgroud)\n

让我们结束吧。模块暴露给编译器:

\n
    \n
  • 从上到下
  • \n
  • 仅供参考\n(这就是为什么在“导入”模块之前你没有智能感知)
  • \n
  • 从入口点开始\n(这是src/main.rs默认src/lib.rs的。\n但它可能是您在 中配置的任何内容Cargo.toml。\n但这与这个问题没有什么关系)
  • \n
\n

通过我们前面的例子,我们得到了顺序:

\n
    \n
  1. src/main.rs->crate

    \n

    因为该crate模块包含mod utils;我们接下来得到:

    \n
  2. \n
  3. src/utils.rssrc/utils/mod.rs->crate::utils

    \n

    因为该utils模块包含mod foo;我们接下来得到:

    \n
  4. \n
  5. src/utils/foo.rs->crate::utils::foo

    \n
  6. \n
\n

  • 谢谢,Rust 书在这方面确实很弱。当您公开 foo 和 bar 时,您是使用 utils::foo 还是只使用 foo?我会怀疑后者? (6认同)
  • 我刚刚在 https://doc.rust-lang.org/reference/items/modules.html#module-source-filenames 中发现“注意:在 rustc 1.30 之前,使用 mod.rs 文件是加载模块的方式带有嵌套子项。鼓励使用新的命名约定,因为它更加一致,并且避免在项目中出现许多名为 mod.rs 的文件。” (2认同)

Jor*_*eña 12

想象一下以下目录结构:

code/
  `- main.rs
   - something/
     `- mod.rs

如果main.rs你在mod something;那里,那么它将查看something/mod.rs文件以用作模块声明的内容something.

替代方法是something.rscode/目录中有一个文件.

所以回顾一下,当你写一个空的模块声明时mod something;,它看起来如下:

  • something.rs在同一目录中调用的文件
  • 在同一目录中调用mod.rs的文件夹中调用something的文件

然后,它使用这些文件中的任何一个的内容作为模块声明的内容.

  • 您可以使用 `#[path = "thefile.rs"]` 属性指定您想要的任何路径,但通常不鼓励这样做,因为我在答案中指定了约定。[参见参考资料](http://doc.rust-lang.org/reference.html#modules)。 (2认同)
  • 1. 当两个文件都存在时会发生什么?`something.rs` 和 `something/mod.rs`?2. 每个文件的默认名称都应该是“mod.rs”,这让搜索成为一种可怕的体验,这不是很奇怪吗? (2认同)