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

Prelude

Prelude 是一组名称,自动带入 crate 中每个模块的作用域。

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

有几个不同的 prelude:

标准库 prelude

每个 crate 都有一个标准库 prelude,它由来自单个标准库模块的名称组成。

使用的模块取决于 crate 的版本,以及 [no_std 属性]是否应用于 crate:

Note

core::panic!std::panic! 之一由于[标准库 prelude]被带入作用域,并且用户编写的glob 导入将另一个带入作用域时,rustc 目前允许使用 panic!,即使它是有歧义的。用户编写的 glob 导入优先以解决此歧义。

有关详细信息,请参阅 names.resolution.expansion.imports.ambiguity.panic-hack

外部 prelude

在根模块中使用 extern crate 导入的外部 crate 或提供给编译器的外部 crate(如 rustc--extern 标志)被添加到外部 prelude。如果使用别名导入(如 extern crate orig_name as new_name),则符号 new_name 被添加到 prelude。

core crate 始终添加到外部 prelude。

只要在 crate 根中未指定 [no_std 属性],就会添加 std crate。

2018 Edition differences

在 2015 版本中,外部 prelude 中的 crate 不能通过 use 声明引用,因此通常的做法是包含 extern crate 声明以将它们带入作用域。

从 2018 版本开始,use 声明可以引用外部 prelude 中的 crate,因此使用 extern crate 被认为是不符合习惯的。

Note

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 带入外部 prelude。

no_std 属性

*no_std 属性*导致 std crate 不被自动链接,并且[标准库 prelude]改为使用 core prelude。

Example

#![no_std]

Note

当 crate 针对不支持标准库的平台或故意不使用标准库的功能时,使用 no_std 很有用。这些功能主要是动态内存分配(例如 BoxVec)以及文件和网络功能(例如 std::fsstd::io)。

Warning

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

no_std 属性使用 MetaWord 语法。

no_std 属性只能应用于 crate 根。

no_std 属性可以在一个形式上使用任意次数。

Note

rustc 会对第一次之后的任何使用发出 lint 警告。

no_std 属性将[标准库 prelude]更改为使用 core prelude 而不是 std prelude。

2018 Edition differences

在 2018 版本之前,默认将 std 注入到 crate 根中。如果指定了 no_std,则注入 core。从 2018 版本开始,无论是否指定 no_std,都不会注入到 crate 根中。

语言 prelude

语言 prelude 包含内置到语言中的类型和属性的名称。语言 prelude 始终在作用域内。

它包含以下内容:

macro_use prelude

macro_use prelude 包含通过应用于 extern crate 的 [macro_use 属性]从外部 crate 导入的宏。

工具 prelude

工具 prelude 包含类型命名空间中外部工具的工具名称。有关更多详细信息,请参阅工具属性部分。

no_implicit_prelude 属性

*no_implicit_prelude [属性]*用于阻止隐式 prelude 被带入作用域。

Example

#![allow(unused)]
fn main() {
// The attribute can be applied to the crate root to affect
// all modules.
#![no_implicit_prelude]

// Or it can be applied to a module to only affect that module
// and its descendants.
#[no_implicit_prelude]
mod example {
    // ...
}
}

no_implicit_prelude 属性使用 MetaWord 语法。

no_implicit_prelude 属性只能应用于 crate 或模块。

Note

rustc 会忽略在其他位置的使用,但会发出 lint 警告。这可能在未来成为错误。

no_implicit_prelude 属性可以在一个形式上使用任意次数。

Note

rustc 会对第一次之后的任何使用发出 lint 警告。

no_implicit_prelude 属性阻止[标准库 prelude]、外部 preludemacro_use prelude工具 prelude被带入模块及其后代的作用域。

Note

尽管有 #![no_implicit_prelude]rustc 目前仍然隐式地将某些宏带入作用域。这些宏是:

例如,这有效:

#![no_implicit_prelude]
fn main() { assert!(true); }

不要依赖此行为;它可能在将来被移除。使用 #![no_implicit_prelude] 时,请始终显式地带入您需要的项。

有关详细信息,请参阅 Rust PR #62086Rust PR #139493

no_implicit_prelude 属性不影响语言 prelude

2018 Edition differences

在 2015 版本中,no_implicit_prelude 属性不影响 macro_use prelude,并且从标准库导出的所有宏仍然包含在 macro_use prelude 中。从 2018 版本开始,该属性确实会移除 macro_use prelude。