03-use 声明
7 分钟阅读
译文 · 基于 The Rust Reference
原文链接: https://doc.rust-lang.org/reference/items/use-declarations.html
r[items.use]
use 声明
r[items.use.syntax]
UseDeclaration -> `use` UseTree `;`
UseTree ->
(SimplePath? `::`)? `*`
| (SimplePath? `::`)? `{` (UseTree ( `,` UseTree )* `,`?)? `}`
| SimplePath ( `as` ( IDENTIFIER | `_` ) )?
r[items.use.intro]
use 声明创建一或多个与某个其他路径同义的局部名称绑定。通常用 use 声明来缩短引用模块项所需的路径。这些声明可以出现在模块和块中,通常位于顶部。use 声明有时也称为导入;若它是公开的,则称为再导出。
r[items.use.forms] use 声明支持若干便利的简写:
r[items.use.forms.multiple]
- 使用花括号语法
use a::b::{c, d, e::f, g::h::i};同时绑定具有公共前缀的一组路径
r[items.use.forms.self]
- 使用
self关键字同时绑定具有公共前缀的一组路径及其公共父模块,例如use a::b::{self, c, d::e};
r[items.use.forms.as]
- 使用语法
use p::q::r as x;将目标名称重新绑定为新的局部名称。也可以与前两项特性组合:use a::b::{self as ab, c as abc}。
r[items.use.forms.glob]
- 使用星号通配符语法
use a::b::*;绑定匹配给定前缀的所有路径。
r[items.use.forms.nesting]
- 多次嵌套上述特性的分组,例如
use a::b::{self as ab, c, d::{*, e::f}};
use 声明的一个例子:
| |
r[items.use.visibility]
use 的可见性
r[items.use.visibility.intro]
与项一样,use 声明默认对其所在模块私有。同样与项一样,若以 pub 关键字限定,use 声明可以是公开的。这样的 use 声明用于再导出一个名称。因此,公开的 use 声明可以把某个公开名称重定向到不同的目标定义:甚至可以是位于另一个模块中、具有私有规范路径的定义。
r[items.use.visibility.unambiguous] 若这样一连串重定向形成环,或无法唯一解析,则构成编译期错误。
再导出的一个例子:
| |
在此例中,模块 quux 再导出了在 foo 中定义的两个公开名称。
r[items.use.path]
use 路径
r[items.use.path.intro]
use 项中允许的路径遵循 [SimplePath] 语法,并类似于表达式中可以使用的路径。它们可以为以下对象创建绑定:
r[items.use.path.disallowed]
它们不能导入关联项、泛型参数、局部变量、带 Self 的路径,或工具属性。更多限制见下文。
r[items.use.path.namespace]
use 会为所导入实体的所有命名空间创建绑定,例外是 self 导入只从类型命名空间导入(如下所述)。例如,下列代码说明了为同一名称在两个命名空间中创建绑定:
| |
r[items.use.path.edition2018]
[!EDITION-2018] 在 2015 edition 中,
use路径相对于 crate 根。例如:
1 2 3 4 5 6 7 8 9 10 11 12mod foo { pub mod example { pub mod iter {} } pub mod baz { pub fn foobaz() {} } } mod bar { // 从 crate 根解析 `foo`。 use foo::example::iter; // `::` 前缀显式从 crate 根解析 `foo`。 use ::foo::baz::foobaz; } # fn main() {}2015 edition 不允许 use 声明引用 extern prelude。因此,在 2015 edition 中仍需
extern crate声明才能在use声明中引用外部 crate。从 2018 edition 开始,use声明可以用与extern crate相同的方式指定外部 crate 依赖。
r[items.use.as]
as 重命名
as 关键字可用于更改导入实体的名称。例如:
| |
r[items.use.multiple-syntax]
花括号语法
r[items.use.multiple-syntax.intro] 可以在路径的最后一段使用花括号,从前一段导入多个实体;若没有前一段,则从当前作用域导入。花括号可以嵌套,从而形成路径树,其中每一组路径段在逻辑上与其父级组合以构成完整路径。
| |
r[items.use.multiple-syntax.empty] 空花括号不导入任何内容,但仍会验证前导路径是可访问的。
r[items.use.multiple-syntax.edition2018]
[!EDITION-2018] 在 2015 edition 中,路径相对于 crate 根,因此诸如
use {foo, bar};的导入会从 crate 根导入名称foo和bar;而从 2018 开始,这些名称相对于当前作用域。
r[items.use.self]
self 导入
r[items.use.self.intro]
关键字 self 可以在花括号语法中使用,以父实体自身的名称为其创建绑定。
| |
注意
self也可以用作路径的第一段。将self用作第一段与在use花括号内使用在逻辑上相同;它表示父段的当前模块,若没有父段则表示当前模块。关于前导self的含义,参见路径一章中的self。
r[items.use.self.trailing]
self 可以出现在 use 路径的最后一段,前面带有 ::。形式为 P::self 的路径等价于 P::{self},而 P::self as name 等价于 P::{self as name}。
| |
注意 关于前导路径的限制,参见 [paths.qualifiers.mod-self.trailing]。
r[items.use.self.module]
当在花括号语法中使用 self 时,花括号组之前的路径必须解析为模块、枚举或 trait。
| |
| |
r[items.use.self.namespace]
self 只从父实体的类型命名空间创建绑定。例如,在下列代码中只导入了 foo 模块:
| |
r[items.use.glob]
Glob 导入
r[items.use.glob.intro]
字符 * 可以用作 use 路径的最后一段,以从前一段实体导入所有可导入的实体。例如:
| |
r[items.use.glob.shadowing] 项和具名导入允许在同一命名空间中遮蔽来自 glob 导入的名称。也就是说,若同一命名空间中已有另一项定义了该名称,则 glob 导入会被遮蔽。例如:
| |
注意 关于不允许遮蔽的情况,参见名称解析歧义。
r[items.use.glob.last-segment-only]
* 不能用作第一段或中间段。
r[items.use.glob.self-import]
* 不能用于将模块的内容导入其自身(例如 use self::*;)。
r[items.use.glob.edition2018]
[!EDITION-2018] 在 2015 edition 中,路径相对于 crate 根,因此诸如
use *;的导入是合法的,表示从 crate 根导入一切。这不能在 crate 根本身中使用。
r[items.use.as-underscore]
下划线导入
r[items.use.as-underscore.intro]
可以使用带下划线的形式 use path as _ 导入项而不绑定到名称。这在导入 trait 以便使用其方法、却又不想导入该 trait 的符号时特别有用,例如该 trait 的符号可能与另一符号冲突。另一个例子是链接外部 crate 而不导入其名称。
| |
r[items.use.as-underscore.glob]
星号 glob 导入会以不可命名的形式导入用 _ 导入的项。
r[items.use.as-underscore.macro]
这些唯一且不可命名的符号在宏展开之后创建,以便宏可以安全地多次发出对 _ 导入的引用。例如,下列代码不应产生错误:
| |
r[items.use.restrictions]
限制
下列规则是合法 use 声明的限制。
r[items.use.restrictions.crate-alias]
使用 crate 导入当前 crate 时,必须使用 as 来定义绑定名称。
| |
r[items.use.restrictions.macro-crate-alias]
在宏转写器中使用 $crate 导入当前 crate 时,必须使用 as 来定义绑定名称。
| |
r[items.use.restrictions.self-alias]
使用 self 导入当前模块时,必须使用 as 来定义绑定名称。
| |
r[items.use.restrictions.super-alias]
使用 super 导入父模块时,必须使用 as 来定义绑定名称。
| |
r[items.use.restrictions.extern-prelude]
不能导入作为 extern prelude 的 ::。
| |
[!EDITION-2018] 在 2015 edition 中,前缀
::指向 crate 根,因此use ::{self as root};是允许的,因为它与use crate::{self as root};相同。从 2018 edition 开始,::前缀指向 extern prelude,不能直接导入。
1use ::{self as root}; //~ Ok
r[items.use.restrictions.duplicate-name]
与任何项定义一样,use 导入不能在模块或块的同一命名空间中创建同名的重复绑定。
r[items.use.restrictions.variant]
use 路径不能通过类型别名引用枚举变体。
| |