预导入项
一个 预导入项 是一组名称的集合,它们会自动被引入到 crate 中每个模块的作用域内。
这些预导入项名称不是模块本身的一部分:它们在 名称解析 期间被隐式查询。例如,即使像 Box 这样的项在每个模块的作用域内,您也不能将其引用为 self::Box,因为它不是当前模块的成员。
有几种不同的预导入项
标准库预导入项
每个 crate 都有一个标准库预导入项,它由一个标准库模块中的名称组成。
使用的模块取决于 crate 的版本,以及是否在 crate 上应用了 no_std 属性
注意
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标志包含。即使在 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 预导入项。 core 和 std 都会被添加到 外部预导入项。
no_std 属性 可以应用在 crate 级别,以防止 std crate 自动被引入作用域。
它会做三件事
- 阻止
std被添加到 外部预导入项。
- 影响用于构成 标准库预导入项 的模块(如上所述)。
- 将
corecrate 注入到 crate 根目录中,而不是std,并将从core导出的所有宏引入macro_use预导入项。
注意
当 crate 定位到不支持标准库的平台,或者有意不使用标准库的能力时,使用 core 预导入项而非标准预导入项非常有用。这些能力主要包括动态内存分配(例如
Box和Vec)以及文件和网络能力(例如std::fs和std::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预导入项。