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}
包含有关模块信息的元组列表。目前,该列表包含具有下列元组Key
S: module
,attributes
,compile
, exportsm
,d5
和native
。元组的顺序和数量可能会改变,恕不另行通知。
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