Erlang宏 #

一、宏概述 #

宏是编译时代码替换机制,用于定义常量、简化代码和条件编译。

二、宏定义 #

2.1 简单宏 #

erlang
-module(simple_macro).
-export([get_version/0]).

-define(VERSION, "1.0.0").
-define(AUTHOR, "Developer").

get_version() -> ?VERSION.

2.2 带参数宏 #

erlang
-module(param_macro).
-export([double/1, square/1]).

-define(DOUBLE(X), (X) * 2).
-define(SQUARE(X), (X) * (X)).

double(X) -> ?DOUBLE(X).
square(X) -> ?SQUARE(X).

2.3 多行宏 #

erlang
-module(multiline_macro).
-export([demo/0]).

-define(LOG(Format, Args),
    io:format("[~p] " ++ Format ++ "~n", [?MODULE | Args])).

demo() ->
    ?LOG("Hello ~s", ["World"]).

三、预定义宏 #

3.1 常用预定义宏 #

说明
?MODULE 当前模块名
?MODULE_STRING 模块名字符串
?FILE 当前文件名
?LINE 当前行号
?MACHINE 机器类型
?OTP_RELEASE OTP版本

3.2 使用示例 #

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

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

四、条件编译 #

4.1 ifdef/endif #

erlang
-module(conditional_compile).
-export([func/0]).

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

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

4.2 ifndef/endif #

erlang
-module(ifndef_demo).
-ifndef(VERSION).
-define(VERSION, "0.0.0").
-endif.

-export([get_version/0]).

get_version() -> ?VERSION.

4.3 if/elif/else/endif #

erlang
-module(if_demo).
-export([get_env/0]).

-ifndef(ENV).
-define(ENV, development).
-endif.

get_env() ->
    if
        ?ENV =:= production -> "Production";
        ?ENV =:= staging -> "Staging";
        true -> "Development"
    end.

五、宏操作符 #

5.1 字符串化 #

erlang
-module(stringify_macro).
-export([demo/0]).

-define(TO_STRING(X), ??X).

demo() ->
    io:format("~s~n", [?TO_STRING(hello)]).

5.2 连接 #

erlang
-module(concat_macro).
-export([demo/0]).

-define(CONCAT(A, B), A ## B).

demo() ->
    ok.

六、最佳实践 #

6.1 使用括号保护 #

erlang
-module(macro_parentheses).
-export([good/1, bad/1]).

-define(GOOD(X), (X) * 2).
-define(BAD(X), X * 2).

good(X) -> ?GOOD(X + 1).
bad(X) -> ?BAD(X + 1).

6.2 避免副作用 #

erlang
-module(macro_side_effects).
-export([good/1, bad/1]).

good(List) ->
    Len = length(List),
    Len + Len.

bad(List) ->
    length(List) + length(List).

七、总结 #

本章学习了:

  • 宏定义
  • 预定义宏
  • 条件编译
  • 宏操作符
  • 最佳实践
最后更新:2026-03-27