GDL 命名空间
GDL 分析程序不允许多次定义同名的模板。 两个独立编写的模板文件可能会无意中对模板使用相同的名称,并阻止你在 GDL 文件中包括这两个模板文件。
为了避免名称冲突问题,GDL 支持命名空间。 头文件的作者可以通过将整个定义包含在 *DefineInNameSpace 构造中来指定每个模板和宏定义应属于哪个命名空间。 作为此构造的实例名称提供的符号将成为所有封闭定义都属于的命名空间。 如果定义驻留在两个或多个嵌套的 *DefineInNameSpace 构造中,它将仅属于最内部 *DefineInNameSpace 构造定义的命名空间。 如果定义不驻留在任何 *DefineInNameSpace 构造中,则会将其分配给默认命名空间或“未命名”命名空间。
如果构成模板或宏构造主体的条目包含在单独的 *DefineInNameSpace 构造中,则分析程序不会将这些单独的条目放在新命名空间中,因为各个条目不是单独的定义,因此它们不能位于不同的命名空间中。 块宏允许嵌套宏定义,这些嵌套定义可以分配给其他命名空间。 但是,更改嵌套定义的命名空间不会延长其生存期。 嵌套宏定义只能在定义它的嵌套级别内引用。
可以在命名空间中以限定或非限定形式引用模板或宏名称。 若要限定模板或宏名称,命名空间名称只需在模板或宏名称的前缀后加上中间冒号字符 (例如 Namespace:MacroName) 。
注意 作为 *Template、宏或 *BlockMacro 定义的值提供的符号名称不能由命名空间限定。 定义的命名空间只能使用 *DefineInNameSpace 进行定义。
例如,在名为“NSName”的命名空间中定义了名为“TEMPNAME”的模板后,该模板可以通过使用命名空间限定表单由另一个模板定义引用,如下面的代码示例所示。
*DefineInNameSpace: NSName
{
*Template: TEMPNAME
{
*% member attributes
}
}
现在可以使用命名空间限定的语法从另一个模板引用此模板,如以下代码示例所示。
*Template: ANOTHER_TEMPLATE
{
*Inherits: NSName:TEMPNAME
}
如果大多数模板引用将引用相同的命名空间,或者如果两个或更多命名空间中引用的模板名称之间没有名称冲突,则可以省略命名空间限定符,仅提供模板名称,并依赖分析程序搜索命名空间列表,直到找到匹配的模板。
命名空间列表通过在 *UsingNameSpace 构造中括起一个或多个 GDL 条目来指定。 如果这些条目中的任何一个包含对模板或宏的非限定引用,则这些引用的解析将受 *UsingNameSpace 构造的影响。 作为此构造的实例名称提供的符号标识要搜索的命名空间。
可以通过嵌套多个构造来指定多个命名空间。 搜索顺序从最内层的 *UsingNameSpace 构造开始,然后向外继续。 如果在指定的命名空间中找到模板定义,则搜索将停止并使用该模板。 如果在搜索所有显式指定的命名空间后未找到匹配项,则分析程序将从最内部构造向外搜索每个封闭 *DefineInNameSpace 构造中命名的命名空间。 如果搜索无法解析引用,它将尝试搜索“未命名”命名空间。
注意 如果需要使命名空间搜索顺序不受外部影响,则应使用 *UsingNameSpace 构造指定解析引用所需的所有命名空间。
不应依赖 *DefineInNameSpace 构造来建立搜索顺序,因为主机可能会使用其他 *UsingNameSpace 构造将包含的文件括起来,并且主机指定的命名空间将在由 *DefineInNameSpace 构造命名的命名空间之前进行搜索。
例如,前面定义的模板显示了已显式指定用于模板名称解析的两个命名空间。 由 *UsingNameSpace 命名的任何命名空间必须以前由 *DefineInNameSpace 定义。 异常是“未命名”命名空间,它始终存在,由 NULL 符号命名。
下面的代码示例演示如何指定“未命名”命名空间来定义搜索顺序。
*UsingNameSpace: NSName2
{
*UsingNameSpace: *%%%%% omitting symbol specifies the Unnamed
*% Namespace.
{
*UsingNameSpace: NSName
{
*Template: ANOTHER_TEMPLATE
{
*Inherits: TEMPNAME
}
}
}
}
在前面的示例中,在显式指定命名空间中的所有搜索都失败后,将搜索“未命名”命名空间,但该示例显式指定在 NSName2 命名空间之前搜索“未命名”命名空间。
由于 GDL 数据条目从不显式引用模板名称,因此使用 *UsingNameSpace 不会影响分配给每个数据条目的模板。 但是,*UsingNameSpace 指定的命名空间搜索顺序 (在分析第一个 GDL 数据条目时生效,) 用于搜索根模板。 如果要包含一个或多个 GDL 头文件,应确保它们不会无意中成为第一个定义数据条目的文件,从而确定用于查找根模板的命名空间。
注意 宏定义受封闭嵌套级别的范围限制。 但是,命名空间嵌套级别不会限制宏定义的范围,因为如果宏的范围不够大,无法在该命名空间之外可见,则不需要将宏定义为属于特定命名空间。
命名空间构造可以在其他类型的构造之间交错。 命名空间构造的显示位置几乎没有限制。 非命名空间构造不会影响命名空间解析。