模块
模块是包含零个或多个 条目 的容器。
模块条目 是用一对花括号括起来的、以 mod
关键字为前缀的、命名的模块。
模块条目将一个新的命名模块引入到组成 crate 的模块树中。模块可以任意嵌套。
一个模块的例子:
#![allow(unused)] fn main() { mod math { type Complex = (f64, f64); fn sin(f: f64) -> f64 { /* ... */ unimplemented!(); } fn cos(f: f64) -> f64 { /* ... */ unimplemented!(); } fn tan(f: f64) -> f64 { /* ... */ unimplemented!(); } } }
模块和类型共享相同的命名空间。
在作用域中使用与模块同名的类型是被禁止的:也就是说,类型定义、trait、struct、enum、union、类型参数或 crate 不能隐藏作用域中模块的名称,反之亦然。使用 use
引入作用域的条目也有此限制。
unsafe
关键字在 mod
关键字之前语法上是允许的,但在语义层面上被拒绝。
这允许宏消耗语法并使用 unsafe
关键字,然后从 token 流中删除它。
模块源码文件名
没有实体的模块将从外部 '文件' 加载。
当模块没有 path
属性时,文件的路径与逻辑 模块路径 相同。
祖先模块路径组件是目录,而模块的内容在一个名为该模块加上 .rs
扩展名的文件中。
例如,下面的模块结构可以有如下的文件系统结构:
模块路径 | 文件系统路径 | 文件内容 |
---|---|---|
crate | lib.rs | mod util; |
crate::util | util.rs | mod config; |
crate::util::config | util/config.rs |
模块文件名也可以是模块的名称作为目录,该目录中的内容在名为 mod.rs
的文件中。
上面的例子也可以使用名称为 util/mod.rs
的文件来表达 crate::util
的内容。
不允许同时存在 util.rs
和 util/mod.rs
。
注意: 注意:在 Rust 1.30 之前,使用
mod.rs
文件是一种加载具有嵌套子模块的方法。推荐使用新的命名约定,因为它更一致,并避免在项目中有许多名为mod.rs
的文件。
path
属性
path
属性可以影响加载外部文件模块时使用的目录和文件。
对于不在内联模块块中的模块上的 path
属性,文件路径相对于源文件所在的目录。
例如,以下代码片段会使用根据其位置而显示的路径:
#[path = "foo.rs"]
mod c;
源代码文件 | c 的文件位置 | c 的模块路径 |
---|---|---|
src/a/b.rs | src/a/foo.rs | crate::a::b::c |
src/a/mod.rs | src/a/foo.rs | crate::a::c |
对于嵌套在内联模块块中的 path
属性,文件路径的相对位置取决于 path
属性所在的源文件类型。
"mod-rs" 源文件是根模块 (例如 lib.rs
或 main.rs
) 以及文件名为 mod.rs
的模块。
"non-mod-rs" 源文件是所有其他模块文件。
在 mod-rs 文件中的内联模块块的 path
属性的路径是相对于 mod-rs 文件的目录,包括内联模块作为目录的组件。
对于非 mod-rs 文件,它是相同的,只是路径以非 mod-rs 模块的名称开头的目录。
例如,以下代码片段将根据其位置使用所示路径:
mod inline {
#[path = "other.rs"]
mod inner;
}
源代码文件 | inner 的文件位置 | inner 的模块路径 |
---|---|---|
src/a/b.rs | src/a/b/inline/other.rs | crate::a::b::inline::inner |
src/a/mod.rs | src/a/inline/other.rs | crate::a::inline::inner |
一个结合了内联模块以及其中嵌套模块的 path
属性的规则的示例 (适用于 mod-rs 和非 mod-rs 文件):
#[path = "thread_files"]
mod thread {
// 从 `thread_files/tls.rs` 中加载 `local_data` 模块,相对于这个源文件的目录。
#[path = "tls.rs"]
mod local_data;
}
模块的属性
模块和所有条目一样,可以接受外围属性,同时也可以接受内部属性,
内部属性可以出现在模块主体的左括号 {
之后,也可以出现在源文件的开头,在可选的 BOM 和执行注解之后。
内置的对模块有意义的属性包括 cfg
、 deprecated
、 doc
、 代码分析检查属性 、 path
和 no_implicit_prelude
。模块还接受宏属性。