Erlang行为 #

一、行为概述 #

行为(Behaviour)是Erlang中的设计模式,定义了一组回调函数接口。

1.1 行为的作用 #

  • 标准化接口
  • 代码复用
  • 分离通用逻辑和特定逻辑
  • 提供框架支持

1.2 内置行为 #

行为 用途
gen_server 通用服务器
gen_statem 状态机
gen_event 事件处理
supervisor 监督者
application 应用程序

二、定义行为 #

2.1 行为模块 #

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

2.2 实现行为 #

erlang
-module(my_behaviour_impl).
-behaviour(my_behaviour).
-export([init/1, handle_request/2, terminate/2]).

init(Args) ->
    {ok, #{args => Args}}.

handle_request({get, Key}, State) ->
    {reply, maps:get(Key, State, undefined), State};
handle_request({set, Key, Value}, State) ->
    {reply, ok, State#{Key => Value}}.

terminate(_Reason, _State) ->
    ok.

三、gen_server #

3.1 基本结构 #

erlang
-module(my_gen_server).
-behaviour(gen_server).
-export([start_link/0, stop/0, get_state/0, set_value/2]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

stop() ->
    gen_server:stop(?MODULE).

get_state() ->
    gen_server:call(?MODULE, get_state).

set_value(Key, Value) ->
    gen_server:cast(?MODULE, {set_value, Key, Value}).

init([]) ->
    {ok, #{}}.

handle_call(get_state, _From, State) ->
    {reply, State, State};
handle_call({get, Key}, _From, State) ->
    {reply, maps:get(Key, State, undefined), State};
handle_call(_Request, _From, State) ->
    {reply, {error, unknown_request}, State}.

handle_cast({set_value, Key, Value}, State) ->
    {noreply, State#{Key => Value}};
handle_cast(_Request, State) ->
    {noreply, State}.

handle_info(_Info, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

3.2 回调函数 #

回调 说明
init/1 初始化
handle_call/3 处理同步调用
handle_cast/2 处理异步调用
handle_info/2 处理消息
terminate/2 终止
code_change/3 热升级

3.3 返回值 #

handle_call返回值:

返回值 说明
{reply, Reply, State} 返回回复
{reply, Reply, State, Timeout} 返回回复带超时
{noreply, State} 不返回回复
{stop, Reason, Reply, State} 停止并返回
{stop, Reason, State} 停止

handle_cast返回值:

返回值 说明
{noreply, State} 继续运行
{noreply, State, Timeout} 继续运行带超时
{stop, Reason, State} 停止

四、gen_statem #

4.1 基本结构 #

erlang
-module(my_statem).
-behaviour(gen_statem).
-export([start_link/0, connect/0, disconnect/0, send_data/1]).
-export([init/1, callback_mode/0, terminate/3, code_change/4]).
-export([idle/3, connected/3]).

start_link() ->
    gen_statem:start_link({local, ?MODULE}, ?MODULE, [], []).

connect() ->
    gen_statem:call(?MODULE, connect).

disconnect() ->
    gen_statem:cast(?MODULE, disconnect).

send_data(Data) ->
    gen_statem:cast(?MODULE, {send_data, Data}).

init([]) ->
    {ok, idle, #{}}.

callback_mode() -> state_functions.

idle({call, From}, connect, State) ->
    {next_state, connected, State, [{reply, From, ok}]};
idle(_, _, State) ->
    {keep_state, State}.

connected(cast, disconnect, State) ->
    {next_state, idle, State};
connected(cast, {send_data, Data}, State) ->
    io:format("Sending: ~p~n", [Data]),
    {keep_state, State};
connected(_, _, State) ->
    {keep_state, State}.

terminate(_Reason, _State, _Data) ->
    ok.

code_change(_OldVsn, State, Data, _Extra) ->
    {ok, State, Data}.

4.2 回调模式 #

模式 说明
state_functions 状态函数模式
handle_event_function 事件处理函数模式

五、gen_event #

5.1 基本结构 #

erlang
-module(my_event_handler).
-behaviour(gen_event).
-export([init/1, handle_event/2, handle_call/2, terminate/2]).

init(Args) ->
    {ok, #{args => Args}}.

handle_event({log, Message}, State) ->
    io:format("Log: ~p~n", [Message]),
    {ok, State};
handle_event({error, Error}, State) ->
    io:format("Error: ~p~n", [Error]),
    {ok, State};
handle_event(_, State) ->
    {ok, State}.

handle_call(get_state, State) ->
    {ok, State, State};
handle_call(_, State) ->
    {ok, {error, unknown_call}, State}.

terminate(_Reason, _State) ->
    ok.

5.2 使用事件管理器 #

erlang
-module(event_manager).
-export([start/0, add_handler/1, notify/1]).

start() ->
    gen_event:start_link({local, my_event_manager}).

add_handler(Handler) ->
    gen_event:add_handler(my_event_manager, Handler, []).

notify(Event) ->
    gen_event:notify(my_event_manager, Event).

六、supervisor #

6.1 基本结构 #

erlang
-module(my_supervisor).
-behaviour(supervisor).
-export([start_link/0, init/1]).

start_link() ->
    supervisor:start_link({local, ?MODULE}, ?MODULE, []).

init([]) ->
    Children = [
        #{id => my_gen_server,
          start => {my_gen_server, start_link, []},
          restart => permanent,
          shutdown => 5000,
          type => worker,
          modules => [my_gen_server]}
    ],
    {ok, {#{strategy => one_for_one, intensity => 1, period => 5}, Children}}.

6.2 重启策略 #

策略 说明
one_for_one 只重启崩溃的子进程
one_for_all 重启所有子进程
rest_for_one 重启崩溃进程及其后的所有进程
simple_one_for_one 简化的one_for_one

6.3 子进程规格 #

erlang
#{id => ChildId,
  start => {Module, Function, Args},
  restart => permanent | transient | temporary,
  shutdown => brutal_kill | integer() | infinity,
  type => worker | supervisor,
  modules => [Module] | dynamic}

七、application #

7.1 应用结构 #

text
my_app/
├── src/
│   ├── my_app.app.src
│   ├── my_app_app.erl
│   └── my_app_sup.erl
├── ebin/
├── priv/
└── test/

7.2 app文件 #

erlang
{application, my_app,
 [{description, "My Erlang Application"},
  {vsn, "1.0.0"},
  {registered, []},
  {mod, {my_app_app, []}},
  {applications,
   [kernel,
    stdlib
   ]},
  {env,[]},
  {modules, [my_app_app, my_app_sup]},
  {licenses, ["MIT"]},
  {links, []}
 ]}.

7.3 application回调 #

erlang
-module(my_app_app).
-behaviour(application).
-export([start/2, stop/1]).

start(_Type, _Args) ->
    my_app_sup:start_link().

stop(_State) ->
    ok.

八、自定义行为 #

8.1 定义行为 #

erlang
-module(cache_behaviour).
-callback init(Options :: term()) -> {ok, State :: term()} | {error, Reason :: term()}.
-callback get(Key :: term(), State :: term()) -> {ok, Value :: term()} | not_found.
-callback put(Key :: term(), Value :: term(), State :: term()) -> {ok, NewState :: term()}.
-callback delete(Key :: term(), State :: term()) -> {ok, NewState :: term()}.
-callback terminate(State :: term()) -> ok.

8.2 实现行为 #

erlang
-module(map_cache).
-behaviour(cache_behaviour).
-export([init/1, get/2, put/3, delete/2, terminate/1]).

init(_Options) ->
    {ok, #{}}.

get(Key, State) ->
    case maps:find(Key, State) of
        {ok, Value} -> {ok, Value};
        error -> not_found
    end.

put(Key, Value, State) ->
    {ok, State#{Key => Value}}.

delete(Key, State) ->
    {ok, maps:remove(Key, State)}.

terminate(_State) ->
    ok.

九、总结 #

本章学习了:

  • 行为的概念
  • 定义行为
  • gen_server
  • gen_statem
  • gen_event
  • supervisor
  • application
  • 自定义行为

准备好学习并发编程了吗?让我们进入下一章。

最后更新:2026-03-27