Erlang显然有一个命名空间的概念,我们每天都使用像application:start()这样的东西。
我想知道是否存在记录名称空间这样的东西。在我的应用程序中,我已经定义了记录用户。一切都很好,直到我需要包括来自rabbitmq的rabbit.hrl,它还定义了 user ,这与我的冲突。
在线搜索无法解决这个问题。我考虑过重命名我的用户记录并在其前面加上一些东西,比如" myapp_user"。这将解决这个特殊问题,直到我怀疑我发现另一个冲突说我的记录"会话"。
我有什么选择?添加前缀" myapp _"我的所有记录都是一个好的做法,或者是否真的支持带有记录的命名空间,而我却找不到它?
编辑:谢谢大家的回答。我所学到的是记录是全球性的。接受的答案非常明确。我将按照我的预期为所有记录添加前缀。
答案 0 :(得分:13)
我认为Erlang没有名称空间。模块是全局的(除了非常不受欢迎的语言扩展),名称是全局的(无论是节点还是集群),pids是全局的,端口是全局的,引用是全局的等等。
一切都平平无息。因此,Erlang中的命名空间是通过约定而不是任何其他方式完成的。这就是您将<appname>_app
,<appname>_sup
等作为模块名称的原因。注册过程也可能遵循该模式和ETS表等。
但是,你应该注意记录本身并不是全局的东西:正如JUST MY correct OPINION所说的那样,记录只是编码技巧而不是元组。因此,它们是模块定义的本地。模块外部没有人会看到记录,除非它们还包括记录定义(通过复制或使用头文件,后者是最好的方法)。
现在我可以争辩说,因为你需要在每个模块的基础上包含.hrl
个文件和记录定义,所以没有命名空间记录;它们在模块中相当范围,就像变量一样。没有理由命名它们:只包括正确的名称。
当然,可能是您包含来自两个模块的记录定义,并且两个记录具有相同的名称。如果发生这种情况,可能需要使用前缀重命名记录,但根据我的经验,这种情况相当罕见。
请注意,将记录公开给其他模块通常也是一个坏主意。这样做的一个问题是,依赖于您的所有模块现在都包含其.hrl
文件。如果您的模块然后更改记录定义,则必须重新编译依赖于它的每个其他模块。更好的做法应该是实现与数据交互的功能。请注意,get(Key,Struct)并不总是一个好主意。如果您可以选择有意义的名称(年龄,姓名,孩子等),您的代码和API应该对读者更有意义。
答案 1 :(得分:4)
您需要以不太可能与其他记录冲突的方式命名所有记录,或者您不需要跨模块使用它们。在大多数情况下,我会将记录视为不透明的数据结构,并为定义访问它的记录的模块添加功能。这样可以避免您遇到的问题。
答案 2 :(得分:3)
我可能会因为他对Erlang更深入的了解而给我提供了可靠的建议,但我很确定Erlang中没有记录的命名空间。记录名称只是一个嫁接到元组前面的原子,编译器在后台为您构建。 (记录几乎只是对元组的破解,你知道。)一旦编译, 没有有意义的“命名空间”用于记录。
例如,让我们看一下这条记录。
-record(branch, {element, priority, left, right}).
在代码中实例化此记录时...
#branch{element = Element, priority = Priority, left = nil, right = nil}.
......另一端出现的是这样的元组:
{branch, Element, Priority, nil, nil}
这就是所有记录。 是没有实际的“记录”对象,因此命名空间实际上没有任何意义。记录的名称只是一个钉在前面的原子。在Erlang中,我完全可以接受那个元组和另一个看起来像这样的元组:
{branch, Twig, Flower}
在运行时级别上同时具有这两个功能都没有问题。
但是...
当然,在代码中将这些作为记录存在问题,因为编译器在实例化时不知道我指的是哪个branch
。简而言之,如果您希望在API中公开记录,则必须执行您所讨论的手动命名空间。
然而,最后一点是关键。为什么要在API中公开记录?我从我的分支记录中获取的代码使用记录作为纯粹不透明的数据类型。我有一个构建分支记录的功能, 是我的API中的内容,如果我想公开一个分支。该函数采用element
,priority
等值并返回一条记录(读取:一个元组)。用户无需了解内容。如果我有一个暴露(生物)树结构的模块,它也可以返回一个碰巧有原子branch
作为其第一个元素而没有任何冲突的元组。
就个人而言,根据我的口味,在Erlang API中暴露记录是代码味道。它有时可能是必要的,但大部分时间它应该保持隐藏。
答案 3 :(得分:1)
只有一个记录命名空间,与功能和宏不同,只能有一个带有名称的记录。但是,对于记录字段,每个记录有一个命名空间,这意味着在不同记录中具有相同名称的字段没有问题。这就是为什么记录名必须始终包含在每个记录访问中的原因之一。