【问题标题】:Why is -compile(export_all) bad practice?为什么 -compile(export_all) 是不好的做法?
【发布时间】:2017-05-17 00:41:57
【问题描述】:

所有的 erlang 书籍似乎都说 export_all 是不好的做法,但没有给出理由。最后,大多数模块将大部分时间花在 compile(export_all) 上,因为不断更新模块列表以删除辅助函数很麻烦。这是不好的做法,因为我应该关心我向其他开发人员公开的功能吗?或者这是不好的做法,因为模块具有的功能数量存在某种性能成本,因为可能是热代码加载之类的事情。如果用大量功能填充模块会影响性能,那有多糟糕?

【问题讨论】:

  • 因为逆向工程更容易并且不必要地生成比需要更大的可执行文件。没有人需要你的函数名在可执行文件中吗?

标签: erlang


【解决方案1】:

有几个原因:

  • 清晰:更容易看出哪些函数打算在模块外使用。

    当您在 Erlang shell 中完成选项卡时,您会得到一个仅包含导出函数的列表,而没有其他函数。重构模块时,您知道哪些函数可以在没有外部用户的情况下安全地重命名。

  • 代码异味:您会收到未使用函数的警告。

    因此,您将避免死代码。

  • 优化:编译器可能能够进行更积极的优化,因为知道并非所有函数都必须导出。

【讨论】:

  • 您有支持优化声明的来源吗?
  • 不幸的是不是,但我想它可以内联仅在一个地方使用的函数,例如,如果它知道永远不会从模块外部调用它们。
  • 此外,它使透析器更难使用。 @jocull 在乔·阿姆斯特朗 (Joe Armstrong) 的《Erlang 编程》一书中,第 2 版,第 1 页。 164,他说当你导出更少的函数时,“编译器可以产生更好的代码”。
【解决方案2】:

虽然我不确定使用 -compile(export_all). 是否会对性能产生任何实际影响,但我怀疑它们是否足够重要。

但是,明确声明导出列表有一个好处。这样大家就可以通过查看.erl文件的第一页来弄清楚模块的接口了。此外,与我们倾向于写下的许多其他内容一样,模块接口的显式声明有助于保持其清晰性。

话虽如此,当我开始开发一个新的 Erlang 模块时,我总是输入 -module(...). -compile(export_all). 接口变得足够成熟后,我添加一个显式的 -export([...]) 同时保留 export_all 编译选项.

【讨论】:

  • 使用-compile(export_all). 不会影响性能。编译器以相同的方式处理所有调用,并且导出的方式与显式导出相同。
【解决方案3】:

明确列出哪些函数是外部函数以及哪些函数是内部函数,这对于将来处理您的代码的任何人都非常有用。我最近一直在重构一些旧代码,而在大多数模块中使用 export_all 一直是令人烦恼的根源。

【讨论】:

    猜你喜欢
    • 2010-10-22
    • 2011-11-20
    • 2015-06-21
    • 2010-11-04
    • 2022-07-05
    相关资源
    最近更新 更多