命名空间
命名空间 是指已声明的 名称 的逻辑分组。基于名称所指代实体的种类,将名称分隔到不同的命名空间中。 允许在不同的命名空间中有相同名称,且不发生冲突。
在一个命名空间内,名称按层次结构组织,每个层次结构都有其自己的命名实体集合。
有几个不同的命名空间,每个命名空间包含不同种类的实体。根据上下文,名称的使用将在不同的命名空间中查找该名称的声明,如 名称解析 章节所述。
以下是命名空间及其相应实体的列表:
- 类型命名空间
- 值命名空间
- 宏命名空间
- 生命周期命名空间
- 标签命名空间
不同命名空间中重复的名称如何可以无歧义地使用的示例:
#![allow(unused)] fn main() { // Foo 在类型命名空间中引入了一个类型和在值命名空间中引入了一个构造函数。 struct Foo(u32); // `Foo` 宏在宏命名空间中声明。 macro_rules! Foo { () => {}; } // `Foo` 在 `f` 参数类型中引用了类型命名空间中的 `Foo` , `'Foo` 引入了生命周期命名空间中的新生命周期。 fn example<'Foo>(f: Foo) { // `Foo` 引用了值命名空间中的 `Foo` 构造函数。 let ctor = Foo; // `Foo` 引用了宏命名空间中的 `Foo` 宏。 Foo!{} // `'Foo` 引入了标签命名空间中的一个标签。 'Foo: loop { // `'Foo` 引用了 `'Foo` 生命周期参数,`Foo` 引用了类型命名空间。 let x: &'Foo Foo; // `'Foo` 引用了该标签。 break 'Foo; } } }
没有命名空间的已命名实体
以下实体具有显式名称,但名称不属于任何特定命名空间。
字段
尽管结构体、枚举和联合体字段是有名称的,但命名字段不属于显式的命名空间。 它们只能通过 字段表达式 访问,该表达式仅检查正在访问的特定类型的字段名称。
use 声明
use 声明 具有命名别名,它们被导入到作用域中,但 use
条目本身不属于特定的命名空间。相反,它可以根据所导入的条目类型将别名引入到多个命名空间中。
子命名空间
宏命名空间被分为两个子命名空间:一个用于 感叹号风格宏 ,一个用于 属性。 当解析属性时,将忽略作用域中的任何感叹号风格宏。 反之,解析感叹号风格宏将忽略作用域中的属性宏。 这样可以防止一个风格覆盖另一个。
例如, cfg
属性 和 cfg
宏 是宏命名空间中具有相同名称的两个不同实体,但它们仍可以在各自的上下文中使用。
无论子命名空间如何, use
导入 覆盖另一个宏仍将导致错误。