命名空间

use-declarations.md
commit: 10da84befd0e79f5e1490912a02cb74368cd3f4a
本章译文最后维护日期:2021-1-25

命名空间是已声明的名称的逻辑分组。根据名称所指的实体类型,名称被分隔到不同的命名空间中。 名称空间允许一个名称空间中出现的名称与另一个名称空间中的相同,且不会导致冲突。

在命名空间中,名称被组织在不同的层次结构中,层次结构的每一层都有自己的命名实体集合。

程序有几个不同的命名空间,每个名称空间包含不同种类的实体。使用名称时将根据上下文来在不同的命名空间中去查找该名称的声明,名称解析一章有讲到这些。

下面是一系列命名空间及其对应实体的列表:

如何清晰地使用不同命名空间中的同名名称的示例:


#![allow(unused)]
fn main() {
// Foo 在类型命名空间中引入了一个类型,在值命名空间中引入了一个构造函数
struct Foo(u32);

// 宏`Foo`在宏命名空间中声明
macro_rules! Foo {
    () => {};
}

// 参数`f` 的类型中的 `Foo` 指向类型命名空间中的 `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` 引用了 `'Foo`标签.
        break 'Foo;
    }
}
}

无命名空间的命名实体

下面的实体有显式的名称,但是这些名称不属于任何特定的命名空间。

字段

即使结构体、枚举和联合体的字段被命名,但这些命名字段并不存在于任何显式的命名空间中。它们只能通过字段表达式访问,该表达式只检测被访问的特定类型的字段名。

use声明

use声明命名了导入到当前作用域中的实体,但 use项本身不属于任何特定的命名空间。相反,它可以在多个名称空间中引入别名,这取决于所导入的程序项类型。

1

目前,在同一个作用域中,标签和生命周期使用相同名称时,rustc 会警告出现命名重复,但编译器内部仍然会独立地区别对待它们。这是一个关于该语言可能扩展的未来兼容性警告。具体见PR #24162