序幕

预导入(prelude) 是一个名称集合,它们会被自动引入到 crate 中每个模块的作用域中。

这些预导入名称并非模块自身的一部分:它们在名称解析期间被隐式查询。例如,即使像 Box 这样的东西在每个模块的作用域中,你也不能将其称为 self::Box,因为它不是当前模块的成员。

有几种不同的预导入

标准库预导入

每个 crate 都有一个标准库预导入,其中包含来自单个标准库模块的名称。使用的模块取决于 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 导入或提供给编译器(如 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,例如 alloctest,不会通过 --extern 标志自动包含进来。即使在 2018 版本中,也必须使用 extern crate 声明将它们引入作用域。

#![allow(unused)] fn main() { extern crate alloc; use alloc::rc::Rc; }

Cargo 仅为 proc-macro crate 将 proc_macro 引入到外部预导入中。

no_std 特性

默认情况下,标准库会自动包含在 crate 根模块中。std crate 会添加到根模块,同时还有一个隐式的 macro_use 特性,它将从 std 导出的所有宏引入到 macro_use 预导入 中。corestd 都被添加到 外部预导入 中。

no_std 特性 可以应用于 crate 级别,以防止 std crate 被自动添加到作用域中。它会做三件事

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

警告: 使用 no_std 并不能阻止标准库被链接进来。将 extern crate std; 放入 crate 仍然是有效的,并且依赖项也可以将其链接进来。

语言预导入

语言预导入包含语言内置的类型和特性的名称。语言预导入始终在作用域中。它包括以下内容

macro_use 预导入

macro_use 预导入包括通过应用于 extern cratemacro_use 特性 导入的外部 crate 中的宏。

工具预导入

工具预导入包括 类型命名空间 中外部工具的工具名称。有关更多详细信息,请参阅工具特性 部分。

no_implicit_prelude 特性

no_implicit_prelude 特性 可以应用于 crate 级别或模块,以指示它不应自动将标准库预导入外部预导入工具预导入引入到该模块或其任何后代的作用域中。

此特性不影响语言预导入

版本差异:在 2015 版本中,no_implicit_prelude 特性不影响 macro_use 预导入,并且从标准库导出的所有宏仍然包含在 macro_use 预导入中。从 2018 版本开始,它将移除 macro_use 预导入。