查看源码 模块
模块语法
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
的元组: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 函数。