前奏
前奏 是一组名称,它们会自动引入到包中每个模块的作用域中。
这些前奏名称不是模块本身的一部分:它们是在 名称解析 期间隐式查询的。例如,即使像 Box
这样的东西在每个模块中都处于作用域内,你也不能将其称为 self::Box
,因为它不是当前模块的成员。
有几种不同的前奏
标准库前奏
每个包都有一个标准库前奏,它由来自单个标准库模块的名称组成。使用的模块取决于包的版本,以及是否将 no_std
属性 应用于包
版本 | 未应用 no_std | 应用了 no_std |
---|---|---|
2015 | std::prelude::rust_2015 | core::prelude::rust_2015 |
2018 | std::prelude::rust_2018 | core::prelude::rust_2018 |
2021 | std::prelude::rust_2021 | core::prelude::rust_2021 |
注意:
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
标志)的外部包将添加到外部前奏 中。如果使用别名导入,例如 extern crate orig_name as new_name
,则符号 new_name
将被添加到前奏中。
core
包始终添加到外部前奏中。只要在包根目录中没有指定 no_std
属性,就会添加 std
包。
版本差异:在 2015 版本中,不能通过 使用声明 引用外部前奏中的包,因此通常的标准做法是包含
extern crate
声明以将它们引入作用域。从 2018 版本开始,使用声明 可以引用外部前奏中的包,因此使用
extern crate
被认为是不规范的。
注意:使用 Cargo 时,
rustc
附带的其他包,例如alloc
和test
,不会使用--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
前奏 中。将 core
和 std
都添加到 外部前奏 中。
no_std
属性 可以应用于包级别,以防止自动将 std
包添加到作用域中。它做了三件事
- 防止将
std
添加到 外部前奏 中。 - 影响使用哪个模块来组成 标准库前奏(如上所述)。
- 将
core
包注入包根目录而不是std
,并将core
导出的所有宏拉入macro_use
前奏 中。
注意:当 crate 的目标平台不支持标准库或有意不使用标准库的功能时,使用核心前奏曲而不是标准前奏曲很有用。这些功能主要是动态内存分配(例如
Box
和Vec
)以及文件和网络功能(例如std::fs
和std::io
)。
警告:使用 no_std
并不能阻止链接标准库。在 crate 中放入 extern crate std;
仍然是有效的,并且依赖项也可以将其链接进来。
语言前奏
语言前奏曲包括语言内置的类型和属性的名称。语言前奏曲始终在作用域内。它包括以下内容
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
前奏曲。