Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

模块

Syntax
Module
      unsafe? mod IDENTIFIER ;
    | unsafe? mod IDENTIFIER {
        InnerAttribute*
        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!();
    }
}
}

模块定义在其所在模块或块的类型命名空间中。

在模块的同一命名空间中定义多个同名程序项是错误的。有关限制和遮蔽行为的更多详细信息,请参见作用域章节

语法上允许 unsafe 关键字出现在 mod 关键字之前,但在语义层面会被拒绝。这允许宏消费该语法并利用 unsafe 关键字,然后将其从 token 流中移除。

模块源文件名

没有主体的模块从外部文件加载。当模块没有 path 属性时,该文件的路径与逻辑模块路径相对应。

祖先模块路径的各级组件是目录,模块的内容以模块名加上 .rs 扩展名命名的文件形式存在。例如,以下模块结构可以有以下对应的文件系统结构:

模块路径文件系统路径文件内容
cratelib.rsmod util;
crate::utilutil.rsmod config;
crate::util::configutil/config.rs

模块文件名也可以是模块名作为目录,其内容放在该目录下一个名为 mod.rs 的文件中。上面的示例也可以将 crate::util 的内容放在文件 util/mod.rs 中。不允许同时存在 util.rsutil/mod.rs

Note

rustc 1.30 之前,使用 mod.rs 文件是加载带有嵌套子模块的模块的方式。鼓励使用新的命名约定,因为它更一致,并且可以避免项目中存在许多名为 mod.rs 的文件。

path 属性

用于加载外部文件模块的目录和文件可以通过 path 属性来影响。

对于不在内联模块块中的模块上的 path 属性,文件路径相对于源文件所在的目录。例如,以下代码片段将根据其位置使用如下所示的路径:

#[path = "foo.rs"]
mod c;
源文件c 的文件位置c 的模块路径
src/a/b.rssrc/a/foo.rscrate::a::b::c
src/a/mod.rssrc/a/foo.rscrate::a::c

对于内联模块块中的 path 属性,文件路径的相对位置取决于 path 属性所在的源文件类型。“mod-rs” 源文件是根模块(如 lib.rsmain.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.rssrc/a/b/inline/other.rscrate::a::b::inline::inner
src/a/mod.rssrc/a/inline/other.rscrate::a::inline::inner

一个结合了上述 path 属性在内联模块和嵌套模块上规则的示例(适用于 mod-rs 和 non-mod-rs 文件):

#[path = "thread_files"]
mod thread {
    // 从 thread_files/tls.rs 加载 `local_data` 模块,相对于
    // 此源文件所在的目录。
    #[path = "tls.rs"]
    mod local_data;
}

模块上的属性

模块和所有程序项一样,接受外部属性。它们也接受内部属性:对于有主体的模块,在 { 之后;或者对于源文件,在可选的 BOM 和 shebang 之后的文件开头。

对模块有意义的内置属性有 cfgdeprecateddoclint 检查属性pathno_implicit_prelude。模块也接受宏属性。