我没有按照通常的计算机科学路线学习编程,并且经常听到有关命名空间的说法,但我并不真正理解这个概念。我在网上找到的描述通常都是在C语言的背景下,而我对此并不熟悉。
我已经学习Ruby两年了,正在努力更深入地理解这门语言和面向对象编程。
我没有按照通常的计算机科学路线学习编程,并且经常听到有关命名空间的说法,但我并不真正理解这个概念。我在网上找到的描述通常都是在C语言的背景下,而我对此并不熟悉。
我已经学习Ruby两年了,正在努力更深入地理解这门语言和面向对象编程。
我将提供一个更加普通的描述。
比如说我的妻子有个名叫Sue的姐姐,而我也有一个名叫Sue的亲戚。在对话中,我该如何区分他们?通过使用他们的姓氏(“Sue Larson”与“Sue Jones”)。姓氏就是命名空间。
当然,这只是一个有限的例子。在编程中,可能的亲戚数量比我的例子要多得多,因此发生冲突的可能性更高。在某些语言中(如Java),命名空间还具有层次结构,这与姓氏没有类似之处。
但总体来说,这是一个类似的概念。
Building::Key
和 Piano::Key
,命名空间将保持 Key
类的分离。 - Nathan Long维基百科对namespace的定义:
命名空间是一个抽象的容器或环境,用于容纳一组独特标识符(即名称)。...
例如,一个可以使用命名空间的地方如下所示:
你定义了一个常量、变量或甚至一个具有通用名称的类。如果你不想重新命名这个常量/变量/类,但需要另一个同名实例,那么你可以在不同的命名空间中定义该新实例。
在 Ruby 中,模块基本上与 C++ 中的命名空间相同。
例如:
module Foo
BAZ = 1
end
module Bar
BAZ = 2
end
puts Foo::BAZ #=> 1
puts Bar::BAZ #=> 2
所以,在这里,你在两个模块(即Ruby中的命名空间)中声明了常量BAZ
只需将其视为对象和功能的逻辑分组
维基百科中有一篇总体介绍命名空间的短文,以及一篇更为详细的计算机科学领域的命名空间文章,其中包括语言特定的示例等。
关键在于,当您无法将名称“逻辑分组”为命名空间时,即您仅具有单个未区分的“空间”,所有名称都在其中,为了避免意外冲突,您最终会笨拙地通过名称前缀等技巧重新实现基本的命名空间功能。例如,“画画”对于艺术家和枪手来说意义完全不同;如果您不能为艺术家和枪手各自设置独立的命名空间,您最终会得到诸如artist_draw
和gunslinger_draw
这样的标识符,并且仍然存在库作者使用不同约定等问题。
来自 php.net:
什么是命名空间?在最广泛的定义中,命名空间是一种封装项目的方式。这可以在许多地方看到抽象概念。例如,在任何操作系统中,目录用于组合相关文件,并作为其中文件的命名空间。作为一个具体的例子,文件foo.txt可以存在于/home/greg和/home/other两个目录中,但是两个foo.txt的副本不能同时存在于同一个目录中。此外,要在/home/greg目录之外访问foo.txt文件,我们必须使用目录分隔符将目录名称添加到文件名前,以获取/home/greg/foo.txt。这个原则在编程世界中也适用于命名空间。
因此,正如另一个帖子提到的那样,命名空间可用于将项分组在一起。
为了解释为什么这可能是有用的,假设你想要为 Wordpress 写一个插件,并且你想创建一个名为 'MyClass' 的类。但问题在于,你不知道其他开发者是否已经使用了名为 'MyClass' 的类来编写了另一个 Wordpress 插件。因此,为避免命名冲突,你将类命名为 'MyPluginMyClass'。这很麻烦,但它可能可以避免命名冲突。