查看源码 模块

模块语法

Erlang 代码被划分为模块。一个模块由一系列的属性和函数声明组成,每个属性和函数声明都以句点 (.) 结尾。

示例

-module(m).          % module attribute
-export([fact/1]).   % module attribute

fact(N) when N>0 ->  % beginning of function declaration
    N * fact(N-1);   %  |
fact(0) ->           %  |
    1.               % end of function declaration

有关函数声明的描述,请参阅函数声明语法

模块属性

模块属性 定义了模块的某个属性。

一个模块属性由一个标签和一个值组成

-Tag(Value).

Tag 必须是一个原子,而 Value 必须是一个字面量项。为了方便用户自定义属性,如果字面量项 Value 具有 Name/Arity 语法(其中 Name 是一个原子,Arity 是一个正整数),则项 Name/Arity 将被转换为 {Name,Arity}

可以指定任何模块属性。这些属性存储在编译后的代码中,可以通过调用 Module:module_info(attributes) 或使用 STDLIB 中的 beam_lib 模块来检索。

一些模块属性具有预定义的含义。其中一些属性的元数为 2,但用户定义的模块属性的元数必须为 1。

预定义的模块属性

预定义的模块属性应放置在任何函数声明之前。

  • -module(Module). - 模块声明,定义模块的名称。名称 Module(一个原子)应与文件名(不包括扩展名 .erl)相同。否则,代码加载将无法按预期工作。

    此属性应首先指定,并且是唯一强制的属性。

  • -export(Functions). - 导出的函数。指定模块内定义的哪些函数可以从模块外部访问。

    Functions 是一个列表 [Name1/Arity1, ..., NameN/ArityN],其中每个 NameI 是一个原子,ArityI 是一个整数。

  • -import(Module, Functions). - 导入的函数。可以像本地函数一样调用,即不带任何模块前缀。

    Module(一个原子)指定要从中导入函数的模块。Functions 是一个列表,与 export 类似。

  • -moduledoc(Documentation).-moduledoc Documentation. - 此模块的用户文档。 Documentation 的允许值与 -doc 的值相同。

    有关如何使用 -moduledoc 的更多详细信息,请参阅文档

  • -compile(Options). - 编译器选项。Options 是单个选项或选项列表。编译模块时,此属性将添加到选项列表中。请参阅 Compiler 中的 compile 模块。

  • -vsn(Vsn). - 模块版本。Vsn 是任何字面量项,可以使用 beam_lib:version/1 检索。

    如果未指定此属性,则版本默认为模块的 MD5 校验和。

  • -on_load(Function). - 此属性命名一个函数,该函数在加载模块时自动运行。有关更多信息,请参阅在加载模块时运行函数

  • -nifs(Functions). - 指定模块内定义的哪些函数可以使用 erlang:load_nif/2 加载为 NIF。

    Functions 是一个列表 [Name1/Arity1, ..., NameN/ArityN],其中每个 NameI 是一个原子,ArityI 是一个整数。

    虽然不是严格必要,但建议在任何加载 NIF 的模块中使用 -nifs() 属性,以便编译器可以做出更好的优化决策。

    在不加载 NIF 的模块中,无需添加 -nifs([])。对于编译器来说,模块内部缺少对 erlang:load_nif/2 的任何调用就足以得出相同的结论。

    更改

    -nifs() 属性的特殊含义是在 Erlang/OTP 25.0 中引入的。在以前的版本中,接受 -nifs(),但没有特殊的含义。

行为模块属性

可以指定模块是行为的回调模块

-behaviour(Behaviour).

原子 Behaviour 给出了行为的名称,它可以是用户定义的行为或以下 OTP 标准行为之一

  • gen_server
  • gen_statem
  • gen_event
  • supervisor

也接受拼写 behavior

可以通过导出的函数 behaviour_info/1 直接指定模块的回调函数

behaviour_info(callbacks) -> Callbacks.

或者为每个回调函数使用 -callback 属性

-callback Name(Arguments) -> Result.

这里,Arguments 是零个或多个参数的列表。应首选 -callback 属性,因为额外的类型信息可以被工具用来生成文档或查找差异。

OTP 设计原则中阅读有关行为和回调模块的更多信息。

记录定义

记录定义使用与模块属性相同的语法

-record(Record, Fields).

记录定义允许在模块中的任何位置,包括函数声明之间。请在记录中阅读更多信息。

预处理器

预处理器使用与模块属性相同的语法,预处理器支持文件包含、宏和条件编译

-include("SomeFile.hrl").
-define(Macro, Replacement).

请在预处理器中阅读更多信息。

设置文件和行

用于更改预定义宏 ?FILE?LINE 使用与模块属性相同的语法

-file(File, Line).

此属性由诸如 Yecc 之类的工具使用,以通知编译器源代码是由另一个工具生成的。它还指示源文件与原始用户编写文件(从中生成源代码)的行之间的对应关系。

类型和函数规范

用于指定类型和函数规范的语法与模块属性的语法类似

-type my_type() :: atom() | integer().
-spec my_function(integer()) -> integer().

请在类型和函数规范中阅读更多信息。

该描述基于 EEP8 - 类型和函数规范,该规范不再更新。

文档属性

模块属性 -doc(Documentation) 用于为函数/类型/回调提供用户文档

-doc("Example documentation").
example() -> ok.

该属性应放置在它所文档化的实体之前。Documentation 周围的括号是可选的。Documentation 的允许值为

  • 字面量字符串utf-8 编码的二进制字符串 - 文档化该实体的字符串。允许使用任何字面量字符串,因此可以使用 三引号字符串和转换为字面量字符串的 sigils。以下示例是等效的

    -doc("Example \"docs\"").
    -doc(<<"Example \"docs\""/utf8>>).
    -doc ~S/Example "docs"/.
    -doc """
       Example "docs"
       """
    -doc ~B|Example "docs"|.

    为了清晰起见,建议使用普通 "strings" 或三引号字符串作为文档属性。

  • {file, file:name/0 } - 读取文件名的内容并将其用作文档字符串。

  • false - 将当前实体设置为隐藏,即不应将其列为可用函数,并且没有文档。

  • Metadata ::map() - 有关当前实体的元数据。元数据中的某些键具有特殊含义。有关更多详细信息,请参阅Moduledoc 元数据Doc 元数据

每个实体可以有多个 Metadata doc 属性,但只允许使用单个文档字符串条目。

有关更多详细信息,请参阅 Erlang 参考手册中的文档指南。

特性指令

虽然不是模块属性,而是指令(因为它可能会影响语法),但有一个 -feature(..) 指令用于启用和禁用 特性

该语法与属性的语法类似,但有两个参数

-feature(FeatureName, enable | disable).

请注意,特性指令只能出现在模块的前缀中。

注释

注释可以放置在模块中的任何位置,除了字符串和带引号的原子内部。注释以字符 % 开头,并持续到但不包括下一个行尾。注释不起作用,本质上等同于空格。

module_info/0 和 module_info/1 函数

编译器会自动将两个特殊的导出函数插入到每个模块中

  • Module:module_info/0
  • Module:module_info/1

调用这些函数时,会检索有关模块的信息。

module_info/0

每个模块中的 module_info/0 函数返回一个 {Key,Value} 元组列表,其中包含有关该模块的信息。在编写本文时,该列表包含具有以下 Key 的元组:moduleattributescompileexportsmd5。元组的顺序和数量可能会在不事先通知的情况下更改。

module_info/1

调用 module_info(Key),其中 Key 是一个原子,将返回有关该模块的单个信息片段。

以下值允许用于 Key

  • module - 返回一个表示模块名称的原子。

  • attributes - 返回一个 {AttributeName,ValueList} 元组列表,其中 AttributeName 是一个属性的名称,而 ValueList 是一个值列表。请注意,如果某个属性在模块中多次出现,则给定的属性可能会在列表中多次出现,并具有不同的值。

    如果模块使用 beam_lib:strip/1 进行剥离,则属性列表将为空。

  • compile - 返回一个元组列表,其中包含有关模块如何编译的信息。如果模块已使用 beam_lib:strip/1 进行剥离,则此列表为空。

  • md5 - 返回一个二进制数据,表示模块的 MD5 校验和。

  • exports - 返回一个 {Name,Arity} 元组列表,其中包含模块中所有导出的函数。

  • functions - 返回一个 {Name,Arity} 元组列表,其中包含模块中所有函数。

  • nifs - 返回一个 {Name,Arity} 元组列表,其中包含模块中所有 NIF 函数。