查看源码 模块
模块语法
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_servergen_statemgen_eventsupervisor
也接受拼写 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/0Module:module_info/1
调用这些函数时,会检索有关模块的信息。
module_info/0
每个模块中的 module_info/0 函数返回一个 {Key,Value} 元组列表,其中包含有关该模块的信息。在编写本文时,该列表包含具有以下 Key 的元组:module、attributes、compile、exports 和 md5。元组的顺序和数量可能会在不事先通知的情况下更改。
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 函数。