预定义
预定义 是一组自动引入到一个 crate 中每个模块作用域的名称。
这些预定义名称不是模块本身的一部分: 它们在 命名解析 期间隐式查询。例如,即使像 Box
这样的内容在每个模块中都处于作用域中,但你无法将其称为 self::Box
,因为它不是当前模块的成员。
有几个不同的预定义:
标准库预定义
每个 crate 都有一个标准库预定义,其中包括来自单个标准库模块的名称。所使用的模块取决于 crate 的版本,以及是否应用了 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
导入的外部 crate 或提供给编译器的 crate (例如使用 rustc
的 --extern
标志) 将被添加到 外部定义 中。如果使用别名导入,例如 extern crate orig_name as new_name
,则符号 new_name
将添加到预定义中。
core
crate 始终会被添加到外部预定义中。只要在 crate 根中未指定 [no_std
属性] , std
crate 也会被添加到预定义中。
版本差异: 在 2015 版中,外部预定义中的 crate 不能通过 use 声明 引用,因此通常的做法是使用
extern crate
声明将它们引入作用域。从 2018 年版开始, use 声明 可以引用外部预定义中的 crate ,因此使用
extern crate
被认为不符合惯例。
注意: 随
rustc
一起提供的其他 crate ,例如alloc
和test
,在使用 Cargo 时不会自动包含在--extern
标志中。它们必须通过extern crate
声明引入作用域,即使在 2018 版中也是如此。#![allow(unused)] fn main() { extern crate alloc; use alloc::rc::Rc; }
对于 proc-macro crate , Cargo 会将
proc_macro
自动添加到外部预定义中。
no_std
属性
默认情况下,标准库会自动包含在 crate 的根模块中。std
crate 与一个隐式的 macro_use
属性 一同添加到根模块,将 std
导出的所有宏都添加到 macro_use
预定义模块 中。同时,core
和 std
也会添加到 extern 预定义 中。
可以在 crate 级别应用 no_std
属性 来阻止自动将 std
crate 添加到作用域中。会做三件事情:
- 防止
std
添加到 extern 预定义 中。 - 影响用于构建 标准库预定义 的模块 (如上所述) 。
- 将
core
crate 注入到 crate 根模块中,而不是std
,并将所有从core
导出的宏添加到macro_use
预定义模块 中。
注意: 当 crate 目标平台不支持标准库或有意不使用标准库的功能时,使用核心预定义而不是标准库预定义很有用。 这些功能主要包括动态内存分配 (例如
Box
和Vec
) 以及文件和网络功能 (例如std::fs
和std::io
) 。
警告: 使用 no_std
不会防止标准库被链接。在 crate 中放置 extern crate std;
是有效的,依赖项依然可以链接它。
语言预定义
语言预定义包括内置于语言中的类型和属性名称。语言预定义始终在作用域内。包括以下内容:
- 类型命名空间
- 布尔类型 —
bool
- 文本类型 —
char
和str
- 整数类型 —
i8
、i16
、i32
、i64
、i128
、u8
、u16
、u32
、u64
、u128
- 与机器相关的整数类型 —
usize
和isize
- 浮点数类型 —
f32
和f64
- 布尔类型 —
- 宏命名空间
macro_use
预定义
macro_use
预定义包括来自外部 crate 的宏,这些宏是通过 [macro_use
] 属性定义的。
工具预定义
工具预定义包括外部工具的工具名称,位于 类型命名空间 中。有关详细信息,请参见 工具属性 部分。
no_implicit_prelude
属性
no_implicit_prelude
attribute 可以应用于 crate 级别或模块上,表示它不应自动为该模块或其任何子级引入 标准库预定义、 extern 预定义 或 工具预定义 。
该属性不影响 语言预定义 。
版本差异:在 2015 版中,
no_implicit_prelude
属性不影响macro_use
预定义 ,并且标准库导出的所有宏仍包含在macro_use
预定义中。从 2018 版开始,将移除macro_use
预定义。