Erlang 的 -import()
指令允许您从其他模块导入代码。它的 include()
指令允许您从 header 导入代码。为什么有理由偏爱其中之一?
我的直觉是,当您不想限定 header 时,headers 适合于简短的、易于编译的代码,例如记录定义。
向您学习一些 Erlang 声明[1]“Erlang 头文件与它们的 C 对应部分非常相似:它们不过是添加到模块中的一段代码,就好像它是在第一个模块中编写的一样地方。”因此,包含似乎会导致编译器在不同模块之间重复工作。头文件似乎是强制性模块系统之上的可选复杂功能。那么我为什么要使用头文件呢?
[1] https://learnyousomeerlang.com/a-short-visit-to-common-data-structures
最佳答案
Erlang 的 -import
只允许您在没有 Module
的情况下调用导入的函数。它会损害易读性,不应使用:您需要检查 import 指令以了解函数是模块的本地函数还是外部函数。
使用头文件,您可以获得与 C
相同的功能,您可以使用它们来共享 -record
定义,而不是拥有类似 dto 的模块 (1),您可以使用它们来包含 -define
以使用相同的宏 (2)。
1:
-record(position, {x, y}).
假设您在整个代码中都有 #position{}
,而不是在所有地方定义记录并在记录定义更改时更新所有副本,您使用 header (或带有不透明类型,但这是另一个问题)。
我们只希望您记得更新所有副本,否则会出现困惑。
2:
-define(ENUM01, enum01).
-define(DEFAULT_TIMEOUT, 1000).
与其到处使用 enum01
和 1000
,这很容易出错并且如果您需要更改它们需要多次更新,您可以在 header 中定义它们并将它们用作?ENUM01
和 ?DEFAULT_TIMEOUT
或者你可以在测试的时候更彻底:
-ifdef(TEST).
-define(assert(A), true = A).
-else
-define(assert(A), A).
-endif.
或者您可以包含一些有用的信息:
-define(LOG(Level, X), logger:log(Level, X, #{line => ?LINE}).
关于import - 为什么 Erlang 既为模块提供 `import`,又为 header 提供 `include`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69065641/