Erlang模块属性 #

一、属性概述 #

模块属性是模块级别的元数据,用于存储模块信息和控制编译行为。

二、预定义属性 #

2.1 module #

erlang
-module(my_module).

定义模块名,必须与文件名相同。

2.2 export #

erlang
-module(export_attrs).
-export([func1/0, func2/1]).
-export([func3/2]).

func1() -> ok.
func2(X) -> X.
func3(A, B) -> {A, B}.

2.3 import #

erlang
-module(import_attrs).
-import(lists, [map/2, filter/2]).

demo(List) ->
    map(fun(X) -> X * 2 end, List).

2.4 export_type #

erlang
-module(type_export).
-export_type([my_type/0, result/0]).

-type my_type() :: integer() | atom().
-type result() :: {ok, term()} | {error, term()}.

2.5 optional_callbacks #

erlang
-module(optional_callbacks).
-optional_callbacks([handle_info/2]).

-callback init(Args :: term()) -> {ok, State :: term()}.
-callback handle_info(Info :: term(), State :: term()) -> {noreply, State :: term()}.

2.6 behaviour #

erlang
-module(gen_server_impl).
-behaviour(gen_server).

-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

init(_Args) -> {ok, #{}}.
handle_call(_Request, _From, State) -> {reply, ok, State}.
handle_cast(_Request, State) -> {noreply, State}.
handle_info(_Info, State) -> {noreply, State}.
terminate(_Reason, _State) -> ok.
code_change(_OldVsn, State, _Extra) -> {ok, State}.

2.7 vsn #

erlang
-module(versioned_module).
-vsn("1.0.0").
-vsn([1, 0, 0]).

2.8 on_load #

erlang
-module(on_load_example).
-on_load(init_module/0).

init_module() ->
    io:format("Module loaded~n"),
    ok.

三、自定义属性 #

3.1 定义属性 #

erlang
-module(custom_attrs).
-author('developer@example.com').
-created('2026-03-27').
-purpose('Example module for custom attributes').
-export([get_attrs/0]).

get_attrs() ->
    ?MODULE:module_info(attributes).

3.2 读取属性 #

erlang
-module(read_attrs).
-author('Alice').
-version('1.0').
-export([get_author/0, get_version/0]).

get_author() ->
    proplists:get_value(author, ?MODULE:module_info(attributes)).

get_version() ->
    proplists:get_value(version, ?MODULE:module_info(attributes)).

3.3 属性列表 #

erlang
-module(attr_list).
-export([get_all/0]).

-tag([important, reviewed, tested]).
-category(examples).

get_all() ->
    ?MODULE:module_info(attributes).

四、编译属性 #

4.1 compile属性 #

erlang
-module(compile_attrs).
-compile([debug_info]).
-compile([export_all]).
-compile({nowarn_unused_function}).
-compile({nowarn_unused_vars}).

unused_func() -> ok.
unused_var() -> X = 1, ok.

4.2 常用编译选项 #

选项 说明
debug_info 包含调试信息
export_all 导出所有函数
{nowarn_unused_function} 不警告未使用函数
{nowarn_unused_vars} 不警告未使用变量
{nowarn_unused_import} 不警告未使用导入
warnings_as_errors 警告视为错误
{outdir, Dir} 输出目录
{i, Dir} 包含目录
{d, Macro} 定义宏
{d, Macro, Value} 定义宏带值

4.3 条件编译 #

erlang
-module(conditional_compile).
-ifdef(TEST).
-compile(export_all).
-endif.

-ifdef(DEBUG).
-define(LOG(X), io:format("DEBUG: ~p~n", [X])).
-else.
-define(LOG(X), ok).
-endif.

func() ->
    ?LOG(called),
    ok.

五、类型属性 #

5.1 type #

erlang
-module(type_attrs).
-export_type([user/0, result/0]).

-type user() :: #{name => string(), age => non_neg_integer()}.
-type result() :: {ok, term()} | {error, term()}.

5.2 opaque #

erlang
-module(opaque_type).
-export_type([handle/0]).
-export([new/0, get_value/1]).

-opaque handle() :: {handle, reference(), term()}.

-spec new() -> handle().
new() ->
    {handle, make_ref(), undefined}.

-spec get_value(handle()) -> term().
get_value({handle, _, Value}) -> Value.

5.3 callback #

erlang
-module(callback_module).
-callback init(Args :: term()) -> {ok, State :: term()} | {error, Reason :: term()}.
-callback handle_call(Request :: term(), From :: {pid(), term()}, State :: term()) -> 
    {reply, Reply :: term(), NewState :: term()} |
    {noreply, NewState :: term()} |
    {stop, Reason :: term(), NewState :: term()}.
-callback terminate(Reason :: term(), State :: term()) -> ok.

六、spec属性 #

6.1 函数规范 #

erlang
-module(spec_attrs).
-export([add/2, divide/2, process/1]).

-spec add(number(), number()) -> number().
add(A, B) -> A + B.

-spec divide(number(), number()) -> {ok, number()} | {error, division_by_zero}.
divide(_, 0) -> {error, division_by_zero};
divide(A, B) -> {ok, A / B}.

-spec process(term()) -> {ok, term()} | {error, term()}.
process(Data) -> {ok, Data}.

6.2 复杂类型规范 #

erlang
-module(complex_spec).
-export([handle_request/1]).

-type method() :: get | post | put | delete.
-type headers() :: [{string(), string()}].
-type body() :: binary() | iolist().
-type request() :: #{method => method(), path => string(), headers => headers(), body => body()}.
-type response() :: #{status => non_neg_integer(), headers => headers(), body => body()}.

-spec handle_request(request()) -> {ok, response()} | {error, term()}.
handle_request(#{method := get, path := Path}) ->
    {ok, #{status => 200, headers => [], body => <<"OK">>}};
handle_request(_) ->
    {error, unsupported_request}.

七、宏属性 #

7.1 define #

erlang
-module(macro_attrs).
-export([get_version/0, double/1]).

-define(VERSION, "1.0.0").
-define(DOUBLE(X), (X) * 2).

get_version() -> ?VERSION.
double(X) -> ?DOUBLE(X).

7.2 条件宏 #

erlang
-module(conditional_macro).
-ifdef(PRODUCTION).
-define(LOG_LEVEL, error).
-else.
-define(LOG_LEVEL, debug).
-endif.

-export([get_log_level/0]).

get_log_level() -> ?LOG_LEVEL.

7.3 预定义宏 #

erlang
-module(predefined_macro).
-export([info/0]).

info() ->
    io:format("Module: ~p~n", [?MODULE]),
    io:format("Module String: ~p~n", [?MODULE_STRING]),
    io:format("File: ~p~n", [?FILE]),
    io:format("Line: ~p~n", [?LINE]),
    io:format("MACHINE: ~p~n", [?MACHINE]),
    io:format("OTP_RELEASE: ~p~n", [?OTP_RELEASE]).

八、最佳实践 #

8.1 属性顺序 #

erlang
-module(best_practice).
-author('developer@example.com').
-vsn("1.0.0").
-behaviour(gen_server).

-include("records.hrl").
-include("macros.hrl").

-export([start_link/0, stop/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

-export_type([state/0]).

-type state() :: #{}.

8.2 文档属性 #

erlang
-module(documented).
-author('Alice <alice@example.com>').
-copyright('2026 Example Inc').
-license('MIT').
-version('1.0.0').
-since('2026-03-27').
-deprecated('Use new_module instead').

8.3 测试属性 #

erlang
-module(test_attrs).
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").

simple_test() ->
    ?assertEqual(2, 1 + 1).
-endif.

九、总结 #

本章学习了:

  • 预定义属性
  • 自定义属性
  • 编译属性
  • 类型属性
  • spec属性
  • 宏属性
  • 最佳实践

准备好学习行为了吗?让我们进入下一章。

最后更新:2026-03-27