预导入项

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

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

有几种不同的预导入项

标准库预导入项

每个 crate 都有一个标准库预导入项,它由一个标准库模块中的名称组成。

使用的模块取决于 crate 的版本,以及是否在 crate 上应用了 no_std 属性

外部预导入项

在根模块中使用 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 标志包含。即使在 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 并不会阻止标准库被链接进来。在 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 预导入项。