Erlang 显然有一个命名空间的概念,我们每天都会使用 application:start()
之类的东西。
我想知道是否有记录命名空间之类的东西。在我的应用程序中,我定义了记录用户。一切都很好,直到我需要包含来自 RabbitMQ 的 rabbit.hrl
,它也定义了 user,这与我的冲突。
在线搜索并没有太多结果来解决这个问题。我考虑过重命名我的用户记录并在其前面添加一些前缀,例如“myapp_user”。这将解决这个特定问题,直到我怀疑我遇到了另一个冲突,比如我的记录“ session ”。
我有什么选择?向我的所有记录添加前缀 myapp_
是一个很好的做法,还是对包含记录的命名空间有真正的支持,但我只是找不到它?
编辑:谢谢大家的回答。我了解到的是,这些记录是全局性的。接受的答案已经说得很清楚了。正如我所期望的那样,我将向所有记录添加前缀。
最佳答案
我认为 Erlang 没有任何命名空间。模块是全局的(除了非常不受欢迎的语言扩展),名称是全局的(对于节点或集群),pid 是全局的,端口是全局的,引用是全局的,等等。
一切都放平了。因此,Erlang 中的命名空间是按照惯例而不是任何其他方式完成的。这就是为什么你有 <appname>_app
, <appname>_sup
等作为模块名称。注册流程也可能遵循该模式以及 ETS 表等。
但是,您应该注意记录本身并不是全局事物:如 JUST MY correct OPINION已经说过,记录只是编译器对元组的把戏。因此,它们对于模块定义来说是本地的。模块外部的任何人都不会看到记录,除非他们还包含记录定义(通过复制它或使用头文件,后者是最好的方法)。
现在我可以说因为你需要包含 .hrl
文件和记录定义基于每个模块,不存在命名空间记录之类的东西;它们在模块中的作用域相当有限,就像变量一样。没有理由给它们命名:只需包含正确的名称即可。
当然,可能存在这样的情况:您包含来自两个模块的记录定义,并且两个记录具有相同的名称。如果发生这种情况,可能需要使用前缀重命名记录,但根据我的经验,这种情况相当罕见。
请注意,将记录公开给其他模块通常也是一个坏主意。这样做的问题之一是,所有依赖于您的模块现在都包含其 .hrl
文件。如果您的模块随后更改了记录定义,您将必须重新编译依赖于它的所有其他模块。更好的做法应该是实现与数据交互的函数。请注意, get(Key, Struct) 并不总是一个好主意。如果您可以选择有意义的名称(年龄、名字、 child 等),您的代码和 API 应该对读者更有意义。
关于erlang 中的命名空间和记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4476108/