【问题标题】:What should and should not be in an Erlang header (.hrl) file?Erlang 头文件 (.hrl) 中应该和不应该有什么?
【发布时间】:2013-05-06 16:33:30
【问题描述】:
我对 .hrl 文件的用途有点困惑。据我了解,.hrl 文件可以包含任何有效的 Erlang 代码,并且使用 -include 指令实质上会将.hrl 文件中的代码插入到包含它的任何模块中。
那么,什么样的代码适合放在这些.hrl 文件中呢? Erlang 的编程规则对记录有如下规定:
如果要在多个模块中使用记录,则应将其定义放在模块中包含的头文件(后缀为 .hrl)中。
因此,我已经养成了在代码中这样做的习惯。但是,我也喜欢将记录的实例化和比较函数以及类型定义等内容放在我的标题中(因为这是我在 C 中会做的事情)。这是不好的形式吗?是否应该从.erl 文件中导出类型,即使它们在多个模块中使用?似乎没有关于可用 Erlang 标头的最佳实践的文档。
【问题讨论】:
标签:
types
coding-style
erlang
standards
header-files
【解决方案1】:
与 C 一样,include 语句实际上将包含文件的内容添加到 erl 文件中。因此,将任何实际代码放入 hrl 文件将导致该代码被复制到您包含它的任何地方。这会导致每个 Erlang 模块中不必要的功能重复。
我会将任何实际的 Erlang 代码放在它自己的 erl 模块中,并将任何记录定义、类型规范或通用宏放在 hrl 文件中。记录定义和类型规范不会编译到二进制文件中,因此它们可以安全地包含在多个文件中。
【解决方案2】:
通常你把东西放在你想在模块之间共享的.hrl 中,通常记录定义和宏。对于您不会放在.hrl 文件中的模块而言,这些内容纯粹是本地的。因此,纯粹的本地记录定义,例如服务器中的本地状态,不会进入.hrl,而只会出现在定义服务器的模块中。与宏定义相同。您应始终避免不必要地公开内部信息。
由于包含文件直接插入到包含文件中,因此其中包含的任何代码都将在包含它的每个模块中复制。您通常不想这样做。
【解决方案3】:
我使用 hrl 文件来存储各种夹具以用于我的单元测试。我不喜欢在实际的生产代码中使用它们。将相同的函数导入不同的位置会使代码难以推理。最好将该代码放在单独的模块中并显式导出。也可以使用 -export_type 指令显式导出类型。
我什至不喜欢与它共享记录(尽管这是共享记录的唯一方式)。为此,我更喜欢让模块只管理具有适当 get 和 set 函数的方法。共享记录是一场等待发生的灾难,让代码升级变得更加棘手。
简而言之,不要将它们用于任何重要的事情。