什么是命名空间?

24

我没有按照通常的计算机科学路线学习编程,并且经常听到有关命名空间的说法,但我并不真正理解这个概念。我在网上找到的描述通常都是在C语言的背景下,而我对此并不熟悉。

我已经学习Ruby两年了,正在努力更深入地理解这门语言和面向对象编程。


10
不要自我贬低-计算机科学学位并不是预测优秀开发人员的好指标,我怀疑全球大多数开发人员都没有这个学位的困扰。 - Mike Woodhouse
7个回答

52

我将提供一个更加普通的描述。

比如说我的妻子有个名叫Sue的姐姐,而我也有一个名叫Sue的亲戚。在对话中,我该如何区分他们?通过使用他们的姓氏(“Sue Larson”与“Sue Jones”)。姓氏就是命名空间

当然,这只是一个有限的例子。在编程中,可能的亲戚数量比我的例子要多得多,因此发生冲突的可能性更高。在某些语言中(如Java),命名空间还具有层次结构,这与姓氏没有类似之处。

但总体来说,这是一个类似的概念。


2
非常感谢您的精彩解释。这样讲解起来真是简单易懂。 - Sam
7
另一个例子:如果在同一个应用程序中有 Building::KeyPiano::Key,命名空间将保持 Key 类的分离。 - Nathan Long

18

维基百科对namespace的定义:

命名空间是一个抽象的容器或环境,用于容纳一组独特标识符(即名称)。...

例如,一个可以使用命名空间的地方如下所示:

你定义了一个常量、变量或甚至一个具有通用名称的类。如果你不想重新命名这个常量/变量/类,但需要另一个同名实例,那么你可以在不同的命名空间中定义该新实例。

在 Ruby 中,模块基本上与 C++ 中的命名空间相同。

例如:

module Foo
  BAZ = 1
end

module Bar
  BAZ = 2
end

puts Foo::BAZ #=> 1
puts Bar::BAZ #=> 2

所以,在这里,你在两个模块(即Ruby中的命名空间)中声明了常量BAZ


15
一个命名空间提供了一个容器来保存诸如函数、类和常量等东西,以便逻辑地将它们分组并帮助避免与其他人编写的同名函数和类发生冲突。
在 Ruby 中,这是通过使用模块来实现的。

3

只需将其视为对象和功能的逻辑分组


3
最简单的答案是:命名空间创建作用域。

在这个上下文中,“作用域”是什么意思? - Andrew Grimm
作用域是与对象关联的封闭上下文。请参考 - http://winterdom.com/dev/cpp/nspaces。你同意吗? - Ninad
命名空间不会创建作用域 - 它们封装在局部作用域中。在计算机编程中,名称绑定的作用域 - 将名称与实体(例如变量)关联起来的区域 - 是程序中名称绑定有效的部分;也就是说,可以在该部分使用名称来引用实体。 - nCardot

2

维基百科中有一篇总体介绍命名空间的短文,以及一篇更为详细的计算机科学领域的命名空间文章,其中包括语言特定的示例等。

关键在于,当您无法将名称“逻辑分组”为命名空间时,即您仅具有单个未区分的“空间”,所有名称都在其中,为了避免意外冲突,您最终会笨拙地通过名称前缀等技巧重新实现基本的命名空间功能。例如,“画画”对于艺术家和枪手来说意义完全不同;如果您不能为艺术家和枪手各自设置独立的命名空间,您最终会得到诸如artist_drawgunslinger_draw这样的标识符,并且仍然存在库作者使用不同约定等问题。


2

来自 php.net:

什么是命名空间?在最广泛的定义中,命名空间是一种封装项目的方式。这可以在许多地方看到抽象概念。例如,在任何操作系统中,目录用于组合相关文件,并作为其中文件的命名空间。作为一个具体的例子,文件foo.txt可以存在于/home/greg和/home/other两个目录中,但是两个foo.txt的副本不能同时存在于同一个目录中。此外,要在/home/greg目录之外访问foo.txt文件,我们必须使用目录分隔符将目录名称添加到文件名前,以获取/home/greg/foo.txt。这个原则在编程世界中也适用于命名空间。

因此,正如另一个帖子提到的那样,命名空间可用于将项分组在一起。

为了解释为什么这可能是有用的,假设你想要为 Wordpress 写一个插件,并且你想创建一个名为 'MyClass' 的类。但问题在于,你不知道其他开发者是否已经使用了名为 'MyClass' 的类来编写了另一个 Wordpress 插件。因此,为避免命名冲突,你将类命名为 'MyPluginMyClass'。这很麻烦,但它可能可以避免命名冲突。
但随着 PHP 5.3 的发布,它终于支持了命名空间(假设 Wordpress 及其部署的所有服务器都升级到 PHP 5.3)。现在,你可以创建一个命名空间,比如 'MyPlugin',并将 'MyClass' 封装在其中。这样做之后,你可以发布你的插件,而不必担心你的版本的 'MyClass' 会与其他人的版本的 'MyClass' 冲突。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接