關於Erlang中的behaviour


唔,聽說過這四個牛逼渣渣的behaviour:gen_server,gen_fsm,gen_event,supervisor。所以也就更加好奇behaviour的實現。

在解釋它是怎么工作的之前,我們可以先看一個具體的實現。這可能會幫助我們理解。

我們先定義一個behaviour:

-module(my_behaviour).
-export([behaviour_info/1]).
-export([start/1, stop/0]).

behaviour_info(callbacks) ->
        [ {init, 1},
         {handle, 2}];
behaviour_info(_Other) ->
        undefined.

start(Mod) ->
        State = Mod:init(0),
        {ok, State2} = Mod:handle(add, State),
        io:format("state : ~p~n", [State2]).

stop() ->
        stop.

然后,我們給他的callback給出具體的定義:

-module(use_my_behaviour).
-behaviour(my_behaviour).

-export([init/1, handle/2]).

init(State) ->
        io:format("init ~p~n", [State]),
        State.

handle(Request, State) ->
        io:format("handle request:~p state:~p~n", [Request, State]),
        State2 = State + 1,
        {ok, State2}.

ok,然后是具體的執行:

$ erlc my_behaviour.erl
$ erlc use_my_behaviour.erl 
use_my_behaviour.erl:2: Warning: behaviour my_behaviour undefined
$ erl
1> my_behaviour:start(use_my_behaviour).
init 0
handle request:add state:0
state : 1
ok
2> my_behaviour:module_info().            
[{exports,[{behaviour_info,1},
           {start,1},
           {stop,0},
           {module_info,0},
           {module_info,1}]},
 {imports,[]},
 {attributes,[{vsn,[81274671739413406355698544269213408364]}]},
 {compile,[{options,[{outdir,"/Users/luozhenxing/work/erlang/behaviour"}]},
           {version,"4.9.4"},
           {time,{2014,7,2,14,56,19}},
           {source,"/Users/luozhenxing/work/erlang/behaviour/my_behaviour.erl"}]}]
3> my_behaviour:behaviour_info(callbacks).
[{init,1},{handle,2}]

 

我們來看看我們做了什么,先看behaviour的定義:

1. 需要一個叫behaviour_info的函數,它的參數只有一個,是一個atom,叫做callbacks。

2. 然后,它的返回是a list of tuples,這些tuple定義了具體的callback的名字,以及他們的參數個數。

3. behaviour具體的執行代碼,雖然我們已經給出了callback的接口,但是總要做點什么的,要不然就不叫behaviour了。如上面的start(Mod),我們在這里使用了Mod中具體的init和handle方法。

接着看behaviour使用的時候,事實上,也只是具體定義了behaviour需要的每個callbacks。

所以我們可以得出結論:

1. hehaviour的定義其實還是使用的module的模板,所以,可以說它是一種特殊的module。

2. 我們可以在定義一個module的時候,只寫一些共性的行為,同時為一些特殊的方法留下callback接口,這一module就是the behaviour module;然后,在具體使用的時候,實現不同的callbacks即可,這一module就是the callback module。這一機制就是behviour機制了。

3. 顯然,一個behaviour module,我們是可以寫很多個callback module配套使用的。

 

另外,R15B之后,提供了另外一種新的定義behaviour的方法(看起來是不是和spec很像?):

-module(some_behaviour).
-callback init( number() ) -> number().
-callback handle( Event :: atom(), ARG::number() ) -> number().

這樣做,和“先定義behaviour_info(callback),然后再將其export出去”效果是一樣的;不同的是,這樣定義之后,Dialyzer可以方便的知道是不是出了什么問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM