前奏

前奏 是一组名称,它们会自动引入到包中每个模块的作用域中。

这些前奏名称不是模块本身的一部分:它们是在 名称解析 期间隐式查询的。例如,即使像 Box 这样的东西在每个模块中都处于作用域内,你也不能将其称为 self::Box,因为它不是当前模块的成员。

有几种不同的前奏

标准库前奏

每个包都有一个标准库前奏,它由来自单个标准库模块的名称组成。使用的模块取决于包的版本,以及是否将 no_std 属性 应用于包

注意:

std::prelude::rust_2015std::prelude::rust_2018 的内容与 std::prelude::v1 相同。

core::prelude::rust_2015core::prelude::rust_2018 的内容与 core::prelude::v1 相同。

外部前奏

在根模块中使用 extern crate 导入或提供给编译器(如使用 rustc--extern 标志)的外部包将添加到外部前奏 中。如果使用别名导入,例如 extern crate orig_name as new_name,则符号 new_name 将被添加到前奏中。

core 包始终添加到外部前奏中。只要在包根目录中没有指定 no_std 属性,就会添加 std 包。

版本差异:在 2015 版本中,不能通过 使用声明 引用外部前奏中的包,因此通常的标准做法是包含 extern crate 声明以将它们引入作用域。

从 2018 版本开始,使用声明 可以引用外部前奏中的包,因此使用 extern crate 被认为是不规范的。

注意:使用 Cargo 时,rustc 附带的其他包,例如 alloctest,不会使用 --extern 标志自动包含。即使在 2018 版本中,也必须使用 extern crate 声明将它们引入作用域。

#![allow(unused)]
fn main() {
extern crate alloc;
use alloc::rc::Rc;
}

Cargo 确实将 proc_macro 引入到仅限过程宏包的外部前奏中。

no_std 属性

默认情况下,标准库会自动包含在包根模块中。将 std 包添加到根目录中,以及一个隐式的 macro_use 属性,将 std 导出的所有宏拉入 macro_use 前奏 中。将 corestd 都添加到 外部前奏 中。

no_std 属性 可以应用于包级别,以防止自动将 std 包添加到作用域中。它做了三件事

注意:当 crate 的目标平台不支持标准库或有意不使用标准库的功能时,使用核心前奏曲而不是标准前奏曲很有用。这些功能主要是动态内存分配(例如 BoxVec)以及文件和网络功能(例如 std::fsstd::io)。

警告:使用 no_std 并不能阻止链接标准库。在 crate 中放入 extern crate std; 仍然是有效的,并且依赖项也可以将其链接进来。

语言前奏

语言前奏曲包括语言内置的类型和属性的名称。语言前奏曲始终在作用域内。它包括以下内容

macro_use 前奏

macro_use 前奏曲包括由应用于 extern cratemacro_use 属性 导入的外部 crate 中的宏。

工具前奏

工具前奏曲在 类型命名空间 中包含外部工具的工具名称。有关更多详细信息,请参阅工具属性部分。

no_implicit_prelude 属性

no_implicit_prelude 属性 可以应用于 crate 级别或模块上,以指示它不应自动将 标准库前奏曲外部前奏曲工具前奏曲 引入该模块或其任何后代的作用域。

此属性不影响 语言前奏曲

版本差异:在 2015 版中,no_implicit_prelude 属性不影响 macro_use 前奏曲,并且从标准库导出的所有宏仍然包含在 macro_use 前奏曲中。从 2018 版开始,它将删除 macro_use 前奏曲。