预导入
一个 预导入 是自动引入到 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 导入或提供给编译器(如使用 rustc 的 --extern 标志)的外部 crate 会被添加到 外部预导入 中。如果使用别名导入(如 extern crate orig_name as new_name),那么符号 new_name 将被添加到 预导入 中。
core crate 总是被添加到 外部预导入 中。
只要在 crate 根中没有指定 no_std 属性,std crate 就会被添加。
2018 版次差异
在 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 仅会为过程宏 crate 将
proc_macro引入 外部预导入。
no_std属性
no_std 属性 会导致 std crate 不被自动链接,标准库预导入 转而使用 core 预导入,且 macro_use 预导入 转而使用从 core crate 导出的宏。
例子
#![no_std]
注意
当 crate 的目标平台不支持标准库,或者是有意不使用标准库的功能时,使用
no_std很有用。这些功能主要是动态内存分配(例如Box和Vec)以及文件和网络功能(例如std::fs和std::io)。
警告
使用
no_std并不阻止链接标准库。在 crate 或其依赖项之一中编写extern crate std仍然是有效的;这将导致编译器将stdcrate 链接到程序中。
no_std 属性使用 MetaWord 语法格式。
no_std 属性只能应用于 crate 根。
no_std 属性可以在一个形式上使用任意次数。
注意
rustc会对第一次之后的任何使用发出 lint。
no_std 属性将 标准库预导入 更改为使用 core 预导入而不是 std 预导入。
默认情况下,从 std crate 导出的所有宏都会被添加到 macro_use 预导入 中。如果指定了 no_std 属性,那么从 core crate 导出的所有宏将转而被放入 macro_use 预导入 中。
2018 版次差异
在 2018 版次之前,
std默认注入到 crate 根中。如果指定了no_std,则注入core代替。从 2018 版次开始,无论是否指定no_std,都不会将两者注入到 crate 根中。
语言预导入
语言预导入包含了语言内置的类型和属性名称。语言预导入始终在作用域内。
它包含以下内容:
macro_use预导入
macro_use 预导入包含了从应用了 macro_use 属性 的 extern crate 导入的外部 crate 中的宏。
工具预导入
工具预导入包含了 类型命名空间 中外部工具的工具名称。有关更多详细信息,请参阅 工具属性 部分。
no_implicit_prelude属性
no_implicit_prelude 属性 用于防止隐式 预导入 被引入作用域。
例子
#![allow(unused)] fn main() { // 该属性可以应用于 crate 根以影响 // 所有模块。 #![no_implicit_prelude] // 或者它可以应用于一个模块,仅影响该模块 // 及其后代。 #[no_implicit_prelude] mod example { // ... } }
no_implicit_prelude 属性使用 MetaWord 语法格式。
no_implicit_prelude 属性只能应用于 crate 或模块。
注意
rustc会忽略在其他位置的使用,但会对其发出 lint。这在未来可能会变成一个错误。
no_implicit_prelude 属性可以在一个形式上使用任意次数。
注意
rustc会对第一次之后的任何使用发出 lint。
no_implicit_prelude 属性阻止 标准库预导入、外部预导入、macro_use 预导入 和 工具预导入 被引入到该模块及其后代的作用域中。
no_implicit_prelude 属性不影响 语言预导入。
2018 版次差异
在 2015 版次中,
no_implicit_prelude属性不影响macro_use预导入,并且从标准库导出的所有宏仍包含在macro_use预导入中。从 2018 版次开始,该属性确实会移除macro_use预导入。