模块

语法

模块 :

      unsafe? mod 标识符 ;

   | unsafe? mod 标识符 {

        内部属性*

        项目*

      }

模块是包含零个或多个 项目 的容器。

模块项目 是一个模块,用大括号括起来,命名,并以关键字 mod 为前缀。模块项目在构成包的模块树中引入一个新的命名模块。模块可以任意嵌套。

模块示例

#![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!();
    }
}
}

模块和类型共享相同的命名空间。禁止声明与作用域中的模块同名的命名类型:也就是说,类型定义、特征、结构体、枚举、联合体、类型参数或包不能与作用域中的模块名称相同,反之亦然。使用 use 引入作用域的项目也有此限制。

从语法上讲,unsafe 关键字允许出现在 mod 关键字之前,但在语义级别上会被拒绝。这允许宏在从词法单元流中删除 unsafe 关键字之前,先使用该关键字。

模块源文件名

没有主体的模块从外部文件加载。当模块没有 path 属性时,文件的路径反映逻辑 模块路径。祖先模块路径组件是目录,模块的内容位于一个文件中,该文件的文件名为模块名加上 .rs 扩展名。例如,以下模块结构可以具有以下对应的文件系统结构

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

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

**注意**:在 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 {
    // Load the `local_data` module from `thread_files/tls.rs` relative to
    // this source file's directory.
    #[path = "tls.rs"]
    mod local_data;
}

模块上的属性

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

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