命名空间
维基百科,自由的百科全书
命名空间(namespace)表示标识符(identifier)的上下文(context)。一个标识符可在多个命名空间中定义,它在不同命名空间中的含义是互不相干的。这样,在一个新的命名空间中可定义任何标识符,它们不会与任何已有的标识符发生冲突,因为已有的定义都处于其它命名空间中。
例如,设Bill是X公司的员工,工号为123,而John是Y公司的员工,工号也是123。由于两人在不同的公司工作,可以使用相同的工号来标识而不会造成混乱,这里每个公司就表示一个独立的命名空间。如果两人在同一家公司工作,其工号就不能相同了,否则在支付工资时便会发生混乱。
这一特点是使用命名空间的主要理由。在大型的计算机程序或文档中,往往会出现数百或数千个标识符。如果不采用命名空间(或类似的方法,见“命名空间的模拟”一节),则很难保证不出现重名的标识符。通过将逻辑上相关的标识符组织成相应的命名空间,可使整个系统更加模块化。
在编程语言中,命名空间是一种特殊的作用域,它包含了处于该作用域内的标识符,且本身也用一个标识符来表示,这样便将一系列在逻辑上相关的标识符用一个标识符组织了起来。许多现代编程语言都支持命名空间。在一些编程语言(例如C++和Python)中,命名空间本身的标识符也属于一个外层的命名空间,也即命名空间可以嵌套,构成一个命名空间树,树根则是无名的全局名空间。
函数和类 scopes can be viewed as implicit namespaces which are inextricably linked with visibility, accessibility, and object lifetime.
目录 |
[编辑] 在常用编程语言中的应用
在C++语言中, 命名空间使用namespace来声明,并使用{ }来界定命名空间的作用域.
例:
namespace foo { int bar; }
在这个作用域中, identifiers can be used exactly as they are declared. 在这个作用域外, 使用命名空间内的标识符必须包括命名空间前缀. 比如, 在 namespace foo
外, bar
必须写为 foo::bar
. C++ includes another construct which makes this verbosity unnecessary. By adding the line
using namespace foo;
to a piece of code, the prefix foo::
is no longer needed.
Code that is not explicitly declared within a namespace is considered to be in the default namespace.
在C++中,命名空间是可以分层的,即具有层次行. This means that within the hypothetical namespace food::soup
, the identifier chicken
refers to food::soup::chicken
if it exists. If it doesn't exist, it then refers to food::chicken
if it exists. If neither exist, chicken
refers to an identifier in the default namespace.
Namespaces in C++ are most often used to avoid naming collisions. Although namespaces are used extensively in recent C++ code, most older code does not use this facility. For example, the entire standard library is defined within namespace std
, and in earlier standards of the language, in the default namespace.
In the Java programming language, the idea of a namespace is embodied in Java packages. All code belongs to a package, although that package need not be explicitly named. Code from other packages is accessed by prefixing the package name before the appropriate identifier, for example class String
in package java.lang
can be referred to as java.lang.String
(this is known as the fully-qualified class name). Like C++, Java offers a construct which makes it unnecessary to type the package name (import
). However, certain features (such as reflection) require the programmer to use the fully-qualified name.
Unlike C++, namespaces in Java are not hierarchical as far as the syntax of the language is concerned. However, packages are named in a hierarchical manner. For example, all packages beginning with java
are a part of the Java platform—the package Template:Javadoc:SE contains classes core to the language, and Template:Javadoc:SE contains core classes specifically relating to reflection.
在Java (象其它语言一样,例如Ada, C#)中, 命名空间(或者按照它的习惯称'包(package)')界定了与语义有关代码的作用域. 例如, 在C#中, namespace System
contains code provided by the system (the .NET framework). How specific these categories are and how deep the hierarchies go differ from language to language.
[编辑] 在XML中的应用
XML虽然不是一个独立的编程语言,但是它的出现使得命名空间的使用变得更为广泛。
An XML namespace is a W3C standard for providing uniquely named elements and attributes in an XML instance. An XML instance may contain element or attribute names from more than one XML vocabulary. If each vocabulary is given a namespace then the ambiguity between identically named elements or attributes can be resolved.
在同一个命名空间里,所有的元素名都必须唯一。
A simple example would be to consider an XML instance that contained references to a customer and an ordered product. Both the customer element and the product element could have a child element "ID_number". References to the element ID_number would therefore be ambiguous unless the two identically named but semantically different elements were brought under namespaces that would differentiate them.
声明一个命名空间使用XML保留的属性xmlns
, 它的值必须是 URI (统一资源标志符) 指代. 比如 xmlns="http://www.w3.org/1999/xhtml". 注意, 事实上URI是不可读的, 但它对XML解析器来说就只是简单不过的字串. 比如, [1] 这个地址本身并不包含任何代码, 它只表示XHTML命名空间. 使用URI (比如 "http://www.w3.org/1999/xhtml") 去标示一个命名空间, 而不是用一个简短的字串 (比如"xhtml"), 这样做是为了减少不同命名空间标示符冲突的可能性.
The declaration can also include a short prefix with which elements and attributes can be identified e.g. xmlns:xhtml="http://www.w3.org/1999/xhtml".
An XML namespace does not require that its vocabulary be defined, though it is fairly common practice to place either a DTD or an XML Schema defining the precise data structure at the location of the namespace's URI.
[编辑] 命名空间的模拟
In programming languages that do not provide language support for namespaces, namespaces can be emulated to some extent by using an identifier naming convention. For example, C libraries such as Libpng often use a fixed prefix for all functions and variables that are part of their exposed interface. Libpng exposes identifiers such as:
png_create_write_struct png_get_signature png_read_row png_set_invalid
This gives reasonable assurance that the identifiers are unique and can therefore be used in larger programs without fear of identifier collisions.
但是,这项技术还有一些缺陷:
- It doesn't scale well to nested namespaces; identifiers become excessively long.
- In effect, all uses of the identifiers must be fully namespace-qualified. Languages with direct support for namespaces usually provide ways for the programmer to declare up front that they wish to use some or all identifiers from a specific namespace, which they can then use without qualification for the remainder of the block.
[编辑] 参见
- Scope (programming)
- name resolution
- Plan 9 - Taking everything is a file metaphor beyond files to names.
- Reiser4 - Naming systems should reflect rather than mold structure.
- Java package
- JavaScript Namespaces