预定义

预定义 是一组自动引入到一个 crate 中每个模块作用域的名称。

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

有几个不同的预定义:

标准库预定义

每个 crate 都有一个标准库预定义,其中包括来自单个标准库模块的名称。所使用的模块取决于 crate 的版本,以及是否应用了 no_std属性

注意

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

core::prelude::rust_2015core::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 ,例如 alloctest ,在使用 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 预定义模块 中。同时,corestd 也会添加到 extern 预定义 中。

可以在 crate 级别应用 no_std 属性 来阻止自动将 std crate 添加到作用域中。会做三件事情:

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

警告: 使用 no_std 不会防止标准库被链接。在 crate 中放置 extern crate std; 是有效的,依赖项依然可以链接它。

语言预定义

语言预定义包括内置于语言中的类型和属性名称。语言预定义始终在作用域内。包括以下内容:

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 预定义。