Skip to content

命名空间 (Namespaces)


命名空间,一种标识符的容器,防止其与其他命名空间或全局作用域中的标识符发生冲突。

语法

vb
Namespace identifier [ Alias "aliasname" ]

statements

End Namespace

参数

identifier

命名空间的名称(包括嵌套名称限定符)。

aliasname

命名空间的替代外部名称。

描述

命名空间是声明域,允许编译器限定标识符名称的搜索范围。其主要目的是对标识符进行逻辑分组,避免同一项目不同部分之间的命名冲突。

这类冲突源于默认只提供一个全局作用域,在其中不应存在命名冲突。使用命名空间,可以更容易地避免此类问题,因为可以避免在全局作用域中定义全局对象。

命名空间不允许直接包含代码,只能包含在该命名空间内声明的过程中。这是因为命名空间不是一个作用域,它不是被执行的东西,它只是可用来保存声明的容器。

在命名空间中声明的任何变量都隐式为静态的,且在整个程序中可见(StaticShared 关键字无用)。因此只允许使用常量初始化器。

用法

Type 等其他声明域不同,命名空间可以分成多个片段。第一个片段作为声明,后续片段作为扩展。命名空间扩展的语法与声明部分完全相同。

同一命名空间内声明或定义的标识符不得冲突。它们可以具有相同的名称,但只能作为重载的一部分。因此,命名空间的行为与 Type 的声明域和全局作用域完全相同。

通过解析运算符(".")访问命名空间标识符,方法是在要使用的标识符名称前加上其所属命名空间的名称。然而,在命名空间内部,这种前缀是不必要的,就像 Type 内部的成员一样。

命名空间成员过程可以在命名空间内部定义。也可以在命名空间外部定义,前提是使用解析运算符(以命名空间名称为前缀)。如此定义的过程必须在命名空间的声明之后出现。

可以在另一个命名空间内定义命名空间。但是,该声明必须出现在包含该命名空间的命名空间的最外层声明级别。命名空间声明不能放在过程体内或 Type 块内。

当命名空间的名称非常复杂时,为该名称定义别名可能很有优势。别名将具有更简单的名称。

命名空间别名的名称不得与同一命名空间(无论是全局作用域还是其他)中其他标识符的名称冲突。

注意:解析器允许定义匿名命名空间(没有 identifier 项),但这是与实际 C++ 功能的唯一相似之处:FB 编译器在此情况下会自动生成多个独立的匿名命名空间,而不是每个模块只生成一个。

FB 匿名命名空间几乎无法使用,因为它们的所有声明都是不可访问的,即使从包含它们的模块体中也是如此。除了在内部封装模块构造函数/析构函数之外,再无他用。

Using (Namespaces) 命令

Using (Namespaces) 允许以简化的方式使用命名空间中的标识符,而无需指定其全名(即命名空间名称后跟 "." 运算符再跟标识符名称)。

每个 Using 命令允许直接使用所引用命名空间的所有标识符。

  • 语法:

Using identifier [, identifier [, ...] ]

  • 参数:

identifier:要使用的命名空间的名称。

  • 用法:

在 Using 命令之后,仍然可以使用命名空间中标识符的全名,但不再是必须的。Using 命令从声明所在行开始有效,直到当前作用域块结束。

如果在 Using 指令之后扩展命名空间,则在命名空间扩展中定义的标识符可以与 Using 指令之前定义的标识符完全相同地使用(即无需使用其命名空间名称的完整表达式)。

当为多个命名空间名称输入 Using 命令时,可能会发生命名冲突。在这种情况下,Using 命令不会报告错误,但如果使用了存在冲突的标识符之一,则会发生错误(使用预期标识符的全名可解决冲突)。

示例

命名空间扩展:

start GeSHi

vb
Namespace A  ' 声明命名空间 A
    Dim As Integer i
End Namespace

Namespace B  ' 声明命名空间 B
    Dim As Integer i
End Namespace

Namespace A  ' 扩展命名空间 A
    Dim As Integer j
End Namespace

end GeSHi

访问命名空间成员:

start GeSHi

vb
Dim As Integer i  ' 在全局作用域声明 i

Namespace A
    Dim As Integer i = 2  ' 在命名空间 A 中声明 i
    Dim As Integer j = 3  ' 在命名空间 A 中声明 j
End Namespace

i = 1    ' 使用全局作用域中的 i (.i)
A.i = 4  ' 使用命名空间 A 中的 i (A.i)

end GeSHi

在命名空间外部定义命名空间内声明的函数:

start GeSHi

vb
Namespace A
    Declare Function f () As Integer  ' 在命名空间 A 中声明 f() (A.f())
End Namespace

Function A.f () As Integer  ' 定义来自命名空间 A 的 f() (A.f())
    Return 0
End Function

end GeSHi

定义嵌套命名空间:

start GeSHi

vb
Namespace A
    Dim As Integer i  ' (A.i)
    Namespace B
        Dim As Integer j  ' (A.B.j)
    End Namespace
End Namespace

end GeSHi

使用 Using (Namespaces) 命令访问:

start GeSHi

vb
Namespace A
    Dim As Integer i  ' 声明 A.i
    Dim As Integer j  ' 声明 A.j
End Namespace

Using A  ' 也可使用命名空间 A 的标识符
i = 1  ' 等价于 A.i
j = 1  ' 等价于 A.j

end GeSHi

Using (Namespace) 命令之后扩展命名空间:

start GeSHi

vb
Namespace A
    Dim As Integer i
End Namespace

Using A

Namespace A
    Dim As Integer j
End Namespace

i = 0  ' 初始化 A.i
j = 0  ' 初始化 A.j

end GeSHi

使用 Using (Namespaces) 命令时本地标识符冲突:

start GeSHi

vb
Namespace A
    Dim As Integer i  ' 声明 A.i
    Dim As Integer j  ' 声明 A.j
End Namespace

Namespace B
    Dim As Integer i  ' 声明 B.i
    Dim As Integer j  ' 声明 B.j
    Using A           ' A.i/j 和 B.i/j 存在冲突,但不报错
End Namespace

Dim As Integer j  ' 在全局作用域也声明 j

Using B
'i = 1   ' 错误:符号访问不明确,需要显式作用域解析(B.i 和 A.i 之间)
B.i = 1  ' 使用全名解决歧义
j = 2    ' 歧义(.j、B.j、A.j 之间)由编译器解决,选择全局作用域中的 .j 覆盖

end GeSHi

参见

  • Namespace
  • Using (Namespaces)
  • Scope...End Scope

返回 目录

基于 FreeBASIC 官方文档翻译 如有侵权请联系我们删除
FreeBASIC 是开源项目,与微软公司无隶属关系