序幕
预导入(prelude) 是一个名称集合,它们会被自动引入到 crate 中每个模块的作用域中。
这些预导入名称并非模块自身的一部分:它们在名称解析期间被隐式查询。例如,即使像 Box
这样的东西在每个模块的作用域中,你也不能将其称为 self::Box
,因为它不是当前模块的成员。
有几种不同的预导入
标准库预导入
每个 crate 都有一个标准库预导入,其中包含来自单个标准库模块的名称。使用的模块取决于 crate 的版本,以及是否对 crate 应用了 no_std
特性
注意:
std::prelude::rust_2015
和std::prelude::rust_2018
的内容与std::prelude::v1
相同。
core::prelude::rust_2015
和core::prelude::rust_2018
的内容与core::prelude::v1
相同。
外部预导入
在根模块中使用 extern crate
导入或提供给编译器(如 rustc
的 --extern
标志)的外部 crate 会被添加到外部预导入中。如果使用别名导入,例如 extern crate orig_name as new_name
,则符号 new_name
将被添加到预导入中。
core
crate 始终添加到外部预导入中。std
crate 会被添加,只要 crate 根模块中没有指定 no_std
特性。
版本差异:在 2015 版本中,外部预导入中的 crate 不能通过 use 声明 引用,因此通常的标准做法是包含
extern crate
声明以将它们引入作用域。从 2018 版本开始,use 声明 可以引用外部预导入中的 crate,因此使用
extern crate
被认为是不符合习惯的。
注意:使用 Cargo 时,与
rustc
一起发布的其他 crate,例如alloc
和test
,不会通过--extern
标志自动包含进来。即使在 2018 版本中,也必须使用extern crate
声明将它们引入作用域。
Cargo 仅为 proc-macro crate 将
proc_macro
引入到外部预导入中。
no_std
特性
默认情况下,标准库会自动包含在 crate 根模块中。std
crate 会添加到根模块,同时还有一个隐式的 macro_use
特性,它将从 std
导出的所有宏引入到 macro_use
预导入 中。core
和 std
都被添加到 外部预导入 中。
no_std
特性 可以应用于 crate 级别,以防止 std
crate 被自动添加到作用域中。它会做三件事
- 阻止将
std
添加到 外部预导入 中。 - 影响用于构成标准库预导入的模块(如上所述)。
- 将
core
crate 注入到 crate 根模块中,而不是std
,并将从core
导出的所有宏拉入macro_use
预导入 中。
注意:当 crate 的目标平台不支持标准库,或者有意不使用标准库的功能时,使用 core 预导入而不是标准预导入非常有用。这些功能主要是动态内存分配(例如
Box
和Vec
)以及文件和网络功能(例如std::fs
和std::io
)。
警告: 使用
no_std
并不能阻止标准库被链接进来。将extern crate std;
放入 crate 仍然是有效的,并且依赖项也可以将其链接进来。
语言预导入
语言预导入包含语言内置的类型和特性的名称。语言预导入始终在作用域中。它包括以下内容
macro_use
预导入
macro_use
预导入包括通过应用于 extern crate
的 macro_use
特性 导入的外部 crate 中的宏。
工具预导入
工具预导入包括 类型命名空间 中外部工具的工具名称。有关更多详细信息,请参阅工具特性 部分。
no_implicit_prelude
特性
no_implicit_prelude
特性 可以应用于 crate 级别或模块,以指示它不应自动将标准库预导入、外部预导入或工具预导入引入到该模块或其任何后代的作用域中。
此特性不影响语言预导入。
版本差异:在 2015 版本中,
no_implicit_prelude
特性不影响macro_use
预导入,并且从标准库导出的所有宏仍然包含在macro_use
预导入中。从 2018 版本开始,它将移除macro_use
预导入。