模块
语法
模块 :
unsafe
?mod
标识符;
|unsafe
?mod
标识符{
内部属性(InnerAttribute)*
项(Item)*
}
模块是一个包含零个或多个项的容器。
模块项(module item)是一个模块,包含在大括号中,具有名称并以关键字 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!(); } } }
模块定义在它们所在的模块或块的类型命名空间中。
在同一模块的同一命名空间中定义多个同名项是错误的。有关限制和 shadowing 行为的更多详细信息,请参见作用域章节。
关键字 unsafe
在语法上允许出现在 mod
关键字之前,但在语义层面会被拒绝。这允许宏在将 `unsafe` 关键字从 token stream 中移除之前,能够使用并消费该语法。
模块源文件名
没有模块体的模块会从外部文件加载。当模块没有 path
属性时,文件路径反映逻辑模块路径。
祖先模块路径组件是目录,模块的内容位于与模块同名并加上 .rs
扩展名的文件中。例如,以下模块结构可以对应这种文件系统结构
模块路径 | 文件系统路径 | 文件内容 |
---|---|---|
crate | lib.rs | mod util; |
crate::util | util.rs | mod config; |
crate::util::config | util/config.rs |
模块文件名也可以是作为目录的模块名称,其内容位于该目录内名为 mod.rs
的文件中。上面的示例也可以通过将 crate::util
的内容放在名为 util/mod.rs
的文件中来表示。不允许同时存在 util.rs
和 util/mod.rs
。
注意
在
rustc
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 文件所在目录的,包括内联模块组件作为目录。对于 non-mod-rs 文件,除了路径以 non-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 和 non-mod-rs 文件)
#[path = "thread_files"]
mod thread {
// Load the `local_data` module from `thread_files/tls.rs` relative to
// this source file's directory.
#[path = "tls.rs"]
mod local_data;
}
模块上的属性
模块与所有项一样,接受外部属性(outer attributes)。它们也接受内部属性(inner attributes):对于有模块体的模块,位于 {
之后;或者位于源文件开头,可选的 BOM 和 shebang 之后。
对模块有意义的内置属性是 cfg
、deprecated
、doc
、lint 检查属性、path
和 no_implicit_prelude
。模块也接受宏属性。