Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

预导入

一个 预导入 是自动引入到 crate 中每个模块作用域的名称集合。

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

有几种不同的 预导入:

标准库预导入

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

所使用的模块取决于 crate 的 版次,以及是否对 crate 应用了 no_std 属性

外部预导入

在根模块中使用 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,例如 alloctest,在使用 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 很有用。这些功能主要是动态内存分配(例如 BoxVec)以及文件和网络功能(例如 std::fsstd::io)。

警告

使用 no_std 并不阻止链接标准库。在 crate 或其依赖项之一中编写 extern crate std 仍然是有效的;这将导致编译器将 std crate 链接到程序中。

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 预导入。