Preludes
预导入包
use-declarations.md
commit: 0181f237f508a8109d99db76a4a5ab48d6132b93
本章译文最后维护日期:2022-03-14
预导入包是一组名称的集合,它会自动把这些名称导入到 crate 中的每个模块的作用域中。
预导入包中的那些名称不是当前模块本身的一部分:它们在名称解析期间被隐式导入。例如,即使像 Box
这样在每个模块的作用域中到处使用的名称,你也不能通过 self::Box
来引用它,因为它不是当前模块的成员。
有几个不同的预导入包:
Standard library prelude
标准库预导入包
每个 crate 都有一个标准库预导入包,此包是一个标准库模块。
具体使用的模块取决于 crate 的版次,以及 no_std
属性是否应用于此 crate:
版次 | 非 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
andcore::prelude::rust_2018
与core::prelude::v1
的内容一致。
Extern prelude
外部预导入包
在根模块中使用 extern crate
导入的外部crate 或直接给编译器提供的的外部crate(也就是在 rustc
命令下使用 --extern
命令行参数选项)会被添加到外部预导入包中。如果使用 extern crate orig_name as new_name
这类别名导入,则符号 new_name
将被添加到此预导入包。
core
crate 总是会被添加到外部预导入包中。只要 no_std
属性没有在 crate根模块中指定,那么std
crate 就会被添加进来
版次差异:在 2015 版中,在外部预导入包中的 crate 不能通过 use声明来直接引用,因此通常标准做法是用
extern crate
将那它们纳入到当前作用域。从 2018 版开始, use声明可以直接引用外部预导入包里的 crate,所以再在代码里使用
extern crate
就会被认为是不规范的。
注意: 随
rustc
一起引入的 crate,如alloc
和test
,在使用 Cargo 时不会自动被包含在--extern
命令行参数选项中。即使在 2018 版中,也必须通过外部crate(extern crate
)声明来把它们引入到当前作用域内。#![allow(unused)] fn main() { extern crate alloc; use alloc::rc::Rc; }
Cargo却会将
proc_macro
带入到编译类型为 proc-macro 的 crate 的外部预导入包中
The no_std
attribute
no_std
属性
默认情况下,标准库自动包含在 crate根模块中。在 std
crate 被添加到根模块中的同时,还会隐式生效一个 macro_use
属性,它将所有从 std
中导出的宏放入到macro_use
预导入包中。默认情况下,core
和 std
都被添加到外部预导入包中。
*no_std
属性*可以应用在 crate 级别上,用来防止 std
crate 被自动添加到相关作用域内。此属性作了如下三件事:
- 阻止
std
crate 被添加进外部预导入包。 - 影响标准库预导入包(前面描述过)具体由哪一个模块组成。
- 使用
core
crate 替代std
crate 来注入到当前 crate 的根模块中,同时把core
crate下的所有宏导入到macro_use
预导入包中。
注意:当 crate 的目标平台不支持标准库或者故意不使用标准库的功能时,使用核心预导入包而不是标准预导入包是很有用的。此时没有导入的标准库的那些功能主要是动态内存分配(例如:
Box
和'Vec
)和文件,以及网络功能(例如:std::fs
和std::io
)。
警告:使用 no_std
并不会阻止标准库被链接进来。使用 extern crate std;
将 std
crate 导入仍然有效,相关的依赖项也可以被正常链接进来。
Language prelude
语言预导入包
语言预导入包包括语言内置的类型名称和属性名称。语言预导入包总是在当前作用域内有效的。它包括以下内容:
- 类型命名空间
- 布尔型 —
bool
- 文本型 —
char
和str
- 整型 —
i8
,i16
,i32
,i64
,i128
,u8
,u16
,u32
,u64
,u128
- 和机器平台相关的整型 —
usize
和isize
- 浮点型 —
f32
和f64
- 布尔型 —
- 宏命名空间
macro_use
prelude
macro_use
预导入包
macro_use
预导入包包含了外部crate 中的宏,这些宏是通过在当前文档源码内部的 extern crate
声明语句上应用 macro_use
属性来导入此声明中的 crate 内部的宏。
Tool prelude
工具类预导入包
工具类预导入包包含了在类型命名空间中声明的外部工具的工具名称。请参阅工具类属性一节,以了解更多细节。
The no_implicit_prelude
attribute
no_implicit_prelude
属性
*no_implicit_prelude
属性*可以应用在 crate级别或模块上,用以指示它不应该自动将标准库预导入包、外部预导入包或工具类预导入包引入到当前模块或其任何子模块的作用域中。
此属性不影响语言预导入包。
版次差异: 在 2015版中,
no_implicit_prelude
属性不会影响macro_use
预导入包,从标准库导出的所有宏仍然包含在macro_use
预导入包中。从 2018版开始,它也会禁止macro_use
预导入包生效。