首页 > 其他 > 详细

Erlang第三课

时间:2014-04-13 00:00:22      阅读:597      评论:0      收藏:0      [点我收藏+]

Erlang里面会把某一类的function放到一个单独的文件中,然后这个整体被叫做Module;Erlang中所有的函数都必须放到Module里面。所以,除了前面两课讲到的基本数据类型,Module也是Erlang的基本元素之一。

 

1、调用函数时,我们必须以这样的结构:Module:Function(Arguments)。除了BIFs。

 

2、BIF(Build In Function)使用时不需要指定module,这是因为虚拟机启动时,默认加载了Erlang这一module里的所有函数进来。所有的arithmetic,logic,和boolean operator这些,也都是在Erlang 这一module中。例如:

bubuko.com,布布扣
> erlang:element(2,{a,b,c}).
b
> element(2,{a,b,c}).
b
> lists:seq(1,4).
[1,2,3,4]
> seq(1,4).
** exception error: undefined shell command seq/2
bubuko.com,布布扣

上面的代码中,不管我们指不指明element函数属于Erlang模块,它都是可以被执行的;另外一面,seq属于lists模块,所以,如果不指定它属于哪个module,系统就会抛出错误。

ps:不是所有Erlang中所有的函数都被加载,有一些不常用的,是没有加载的。

 

3、除了需要一个单独的文件,并且给他起一个别致的名字以外,Functions和Attributes这两样也是一个Module不可缺少的。Function不必多讲,没有Function,建立Module做什么?OK,那Attributes又是做什么用的?Attributes里面存放了描述Module自身用的一些metadata,比如它自己的名字,哪些函数是外部可以调用的,代码作者啊等等这些。编译器会将这些信息放到编译完的代码中去。这样,即使是拿到编译过的代码,我们也可以查看这个module的基本信息,而不用再去翻source code。

attributes的定义方法是 -Name(Attribute)。

 

4、第一个Attributes必须是“-module(Name)”;这里的Name还必须和存放Module的file同名。这里的name便是我们按照MF(A)这样调用函数时,必须要用到的module name。

 

5、然后另一个必不可少的Attributes是" -export([Function1/Arity, Function2/Arity,...,Function3/Arity])"。其中,Function是函数名称,Arity是这个函数接受几个参数。在Erlang中,相同名称不同参数个数的函数是当做不同函数对待的,这类似OOP里面的重载。

 

6、还有一个attributes比较重要“-import(Module, [Function/Arity, ..., Function/Arity])”,其作用就是将module中的函数加载进来,然后,我们调用的时候就直接F(A)即可(就像虚拟机一开始对Erlang这一module做的一样)。这里有个问题,很多人都不大赞成用import来完成工作。主要因为,本来在设计module的时候,只需要考虑function name在本module内唯一就好了,但是,现在如果从不同的module引入function,使用的时候,就得小心翼翼了。

 

7、define是另一个比较重要的attributes,使用方法是“-define(MACRO, some_value)”。这个和C中的define有点像。同样的define也是常被用来定义一些常量和短的函数。Erlang的宏定义使用的时候,格式为“?MACRO”。

ps:?MODULE会被换成module name,as a atom;?FILE会被换成本文件的filename,as a string;?LINE会被换做所在行的行号。

ps:同样的我们可以使用-ifdef(MACRO),-else和-endif等宏定义检查语句,比如:

-ifdef(DEBUGMODE).
-define(DEBUG(S), io:format("dbg: "++S)).
-else.
-define(DEBUG(S), ok).
-endif.

如此,我们可以在后面的代码中使用?DEBUG("entering xxx function!~n")这样的语句来添加调试信息。这样,如果我们如果在编译的时候使用了DEBUGMODE开关,那么,调试信息将被打印出来;如果我们没有使用DEBUGMODE开关,这句只是被替换为ok这一atom,单独这样一条语句的话,是什么也不会做。

 

8、函数的定义语法是Name(Args) -> Body:Name必须是一个atom;Body可以是一条或者多条由逗号隔开的Erlang语句。

 

so,一个module就这样建好了,一起来看看我们建的第一个module:

bubuko.com,布布扣
-module(helloworld).
-export([greet_and_add_two/1]).

add(A,B) ->
    A + B.
    
%%% Shows greeting.
%%% io:format/1 is the standard function used to output text.

hello() ->
    io:format("Hi Erlang!~n").
    
greet_and_add_two(X) ->
    hello(),
    add(X,2).
bubuko.com,布布扣

 然后我们尝试编译并使用我们module:

bubuko.com,布布扣
> cd("C:/Users/zhenxingluo/Documents/Erlang").
C:/Users/zhenxingluo/Documents/Erlang
ok
> c(helloworld).
{ok,helloworld}  
> helloworld:greet_and_add_two(3).
Hi Erlang!
5
> helloworld:module_info().
[{exports,[{greet_and_add_two,1},
           {module_info,0},
           {module_info,1}]},
 {imports,[]},
 {attributes,[{vsn,[251566447801502640269456451546098169641]}]},
 {compile,[{options,[]},
           {version,"4.8.1"},
           {time,{2014,4,2,7,22,18}},
           {source,"c:/Users/zhenxingluo/Documents/Erlang/helloworld.erl"}]}]
bubuko.com,布布扣

这里的cd是Erlang shell专用的一个函数,就是change directory。然后,我们调用Erlang shell中的编译函数c()。如果编译没有报错,我们就会看到helloworld.erl文件的旁边,有生成一个文件叫helloworld.beam。事实上,beam代表Bogdan/Bjorn‘s Erlang Abstract Machine;这个VM只是众多Erlang的虚拟机之一,但是好像其他都不怎么用了。恩,继续编译没有报错的话,因为我们当前目录是helloworld.beam所在目录,所以,VM是看得见这个文件的。那么,我们就可以在shell窗口里直接调用他了。就像我们看到的那样。

这里的module_info()是编译器加入的一个函数,调用此函数可以查看我们module的metadata。同时,它也支持我们使用module_info/1,来查看其中的一项,比如,helloworld:module_info(attributes).

Erlang第三课,布布扣,bubuko.com

Erlang第三课

原文:http://www.cnblogs.com/pied/p/3640621.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!