在线文档教程
Erlang 20

5.模块 | 5. Modules

5个模块

5.1模块语法

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

有关函数声明的描述,请参见Function Declaration Syntax

5.2模块属性

模块属性定义的模块的某些特性。

模块属性由标记和值组成:

-Tag(Value).

Tag必须是原子,而Value必须是一个字面术语。为了方便用户定义属性,如果文字词语Value具有语法Name/Arity(其中Name是原子和Arity正整数),则将该词语Name/Arity翻译为{Name,Arity}

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

几个模块属性具有预定义的含义。其中一些有两个,但用户定义的模块属性必须有一个。

预定义模块属性

预定义的模块属性将放在任何函数声明之前.

-module(Module).

模块声明,定义模块的名称。名称Module,原子与文件名减去扩展名相同.erl。否则code loading不能按预期工作。

该属性将首先被指定,并且是唯一的必需属性。

-export(Functions).

导出的函数。指定在模块内定义的哪些功能在模块外部可见。

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

-import(Module,Functions).

导入的功能。可以像本地函数一样被调用,也就是说,没有任何模块前缀。

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

-compile(Options).

编译器选项。Options是一个选项或一个选项列表。该属性在编译模块时被添加到选项列表中。请参阅compile(3)编译器中的手册页。

-vsn(Vsn).

模块版本。Vsn是任何字面术语,可以使用beam_lib:version/1,请参阅beam_lib(3)STDLIB中的手册页。

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

-on_load(Function).

这个属性命名了一个在模块加载时自动运行的函数。有关更多信息,请参阅Running a Function When a Module is Loaded

行为模块属性

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

-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 Design Principles

记录定义

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

-record(Record,Fields).

记录定义可以在模块中的任何地方使用,也可以在函数声明中使用。阅读更多Records

预处理器

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

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

阅读更多Preprocessor

设置文件和行

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

-file(File, Line).

该属性由工具(如Yecc)用于通知编译器源程序由其他工具生成。它还表示源文件与原始用户编写文件的行之间的对应关系,源文件将从该文件生成。

类型和功能规格

与模块属性类似的语法用于指定类型和功能规格:

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

阅读更多Types and Function specifications

描述是基于EEP8 - Types and function specifications,不需要进一步更新。

5.3评论

注释可以放在模块中的任何地方,除了字符串和引用原子之外。评论以字符“%”开始,继续,但不包括下一行结束,并且没有影响。请注意,终止行尾具有空白效果。

5.4 module_info/0和module_info/1函数

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

  • Module:module_info/0

  • Module:module_info/1

可以调用这些函数来检索有关模块的信息。

module_info/0

module_info/0每个模块中的函数返回{Key,Value}包含有关模块信息的元组列表。目前,该列表包含具有下列元组KeyS: moduleattributescompileexportsmd5native。元组的顺序和数量可能会改变,恕不另行通知。

module_info/1

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

以下值允许用于Key

module

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

attributes

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

如果使用模块剥离beam_lib(3)模块(在STDLIB中),则属性列表将变为空。

compile

返回包含有关模块编译方式信息的元组列表。如果模块已用beam_lib(3)模块剥离(在STDLIB中),此列表为空。

md5

返回表示模块的MD5校验和的二进制文件。如果模块加载了本机代码,则这将是本机代码的MD5,而不是BEAM字节代码。

exports

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

functions

返回{Name,Arity}模块中包含所有函数的元组列表。

native

如果模块具有本地编译代码,则返回true。否则返回false。在没有HiPE支持的情况下编译的系统中,结果总是false