唔,听说过这四个牛逼渣渣的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可以方便的知道是不是出了什么问题。

——————

关于Erlang中的behaviour的更多相关文章

  1. Erlang/OTP:基于Behaviour的回调函数

    原始链接:https://blog.zhustec.me/posts/erlang-otp-1-callback-based-on-behaviour OTP 是什么 OTP 的全称是开源电信平台 ( ...

  2. Erlang中一些错误或者异常的标识

    erlang中错误大体分为四种: 1. 编译错误    2. 逻辑错误    3. 运行时错误    4. 用户代码生成的错误 编译错误,主要是编译器检测出的代码语法错误 逻辑错误,是指程序没有完成预 ...

  3. Erlang中atom的实现

    Erlang的原子(atom)在匹配中有着重要作用,它兼顾了可读性和运行效率. 通过atom,可以实现很多灵活高效的应用. atom可以看作是给字符串生成了一个ID,内部使用的是ID值,必要时可以取出 ...

  4. [erlang 001] erlang中的错误及异常处理

    一. erlang中的错误 1. 分类 1) 编译错误:主要是编译器检测出的代码语法错误: 2) 逻辑错误:是指程序没有完成预期的工作,属于开发人员的问题: 3) 运行时错误:是指erlang运行时抛 ...

  5. erlang中的原子(atom)内部实现[转]

    转自: http://www.kongqingquan.com/archives/208#more-208 Erlang中的atom由通用hash表实现,虚拟机中atom最终的用数值表示,对应表中的下 ...

  6. Erlang中atom的实现[转]

    转自: http://www.cnblogs.com/zhengsyao/p/3424539.html 在 Erlang 中,使用 atom 既方便又高效,我们就来看看 atom 是怎么实现的.ato ...

  7. Socket的UDP协议在erlang中的实现

    现在我们看看UDP协议(User Datagram Protocol,用户数据报协议).使用UDP,互联网上的机器之间可以互相发送小段的数据,叫做数据报.UDP数据报是不可靠的,这意味着如果客户端发送 ...

  8. erlang中字符编码转换(转)

    转自:http://www.thinksaas.cn/group/topic/244329/ 功能说明: erlang中对各种语言的编码支持不足,此代码是使用erlang驱动了著名的iconv编码库来 ...

  9. Erlang中日志管理

    http://blog.sina.com.cn/s/blog_96b8a1540101317g.html 一.基本概念 在Erlang中,通过两个概念管理错误事情:事件管理器(event manage ...

随机推荐

  1. 使用idea15搭建基于maven的springmvc-mybatis框架

    我这边使用的是intellij idea15 1.new maven webapp project 2.添加groupId和artifactId 3.选择maven路径和maven仓库路径 最后确定之 ...

  2. Lua热更系统

    1.介绍 使用脚本开发游戏业务逻辑其中一个好处就是代码可线上热更,不停机修复bug.而热更代码的写法与需要被热更的文件的代码又有着密切的关系,本文介绍一种热更方法. 2.热更原理 Lua提供一个叫re ...

  3. repeater重复器、地址栏传值、response

    repeater重复器: <HeaderTemplate> <ItemTemplate> <AlternatingItemTemplate> <FooterT ...

  4. Linux 内核编译

    注:该文章部分内容摘录自以下链接. http://www.cnblogs.com/zhunian/archive/2012/04/04/2431883.html 创建内核的第一步是创建一个 .conf ...

  5. Deep Learning 22:总结一些deep learning的基本知识

    1.交叉熵代价函数 2.正则化方法:L1和L2 regularization.数据集扩增.dropout 3. 数据预处理 4.机器学习算法中如何选取超参数:学习速率.正则项系数.minibatch ...

  6. easyui 复选框 onClickRow事件与onSelect事件与onCheck事件

    在项目中一直存在一个问题,一直都没发现问题的根源在哪里.在我们测试这边也是偶尔会出现.但是每次我去测试的时候也没问题.今天终于找到原因了! 在easyui中点击行和点击复选框触发的事件是不一样的! 点 ...

  7. grep 使用或条件 ( grep -e )

    test@k1rhel5822161:/home/test>cat 31 52 33 24567test@k1rhel5822161:/home/test>grep -e '2|3' 3t ...

  8. 联想键盘 去掉fn

    这个帖子 很实用 http://iknow.lenovo.com/detail/dc_039949.html 键盘驱动下载地址:http://support1.lenovo.com.cn/lenovo ...

  9. ASP.NET 控件前缀命名规范

    标准控件 1  btn Button 2  chk CheckBox 3  ckl CheckedListBox 4  cmb ComboBox 5  dtp DateTimePicker 6  lb ...

  10. JAVA 线程中的异常捕获

    在java多线程程序中,所有线程都不允许抛出未捕获的checked exception(比如sleep时的InterruptedException),也就是说各个线程需要自己把自己的checked e ...