zoukankan      html  css  js  c++  java
  • 关于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可以方便的知道是不是出了什么问题。

  • 相关阅读:
    秘密
    WPF中不规则窗体与WebBrowser控件的兼容问题解决办法
    照片批量压缩、缩放、加水印工具
    在配置文件(.settings、.config)中存储自定义对象
    糟糕之至的用户体验——JavaEye你怎么就这么贱!
    AWWWB 网站克隆器 更新到1.02 修正错误
    简单的文本片段替换器
    AWWWB 网站克隆器 更新到1.01 修正错误
    2010年微软最有价值专家奖(MVP)大礼包
    WebGet2——自动爬网页工具
  • 原文地址:https://www.cnblogs.com/pied/p/3821363.html
Copyright © 2011-2022 走看看