Erlang 语言入门-1

来源:互联网 发布:乐高机器人编程培训 编辑:程序博客网 时间:2024/04/28 12:01

Erlang 语言入门-1

1、顺序型编程

1.1 Erlang Shell
同现在的一些语言类似,如Python、Ruby等,都提供一个命令行解释界面(Shell)

,Erlang也提供了类似的一个节目。Windows下面是werl.exe,这个程序的快捷方

式可以在“开始菜单”里面找到。
执行程序,可以看到:

Erlang (BEAM) emulator version 5.5.3 [a

Eshell V5.5.3  (abort with ^G)
1>

现在可以输入"2+5",并且以“."接受输入
1>2 + 5.
7
2>

可以看到erlang计算的结果是7(哈哈,一个显而易见的答案...)

1.2模块(Module)和函数(Function)
如果仅仅从Shell里面一行一行的输入,显然不能满足需要。现在,我们可以拿出

自己心爱的编辑器,编写一个Erlang程序。如果你足够幸运能够找到支持Erlang

语法的编辑器,对于程序的编写应该有非常大的帮助。
输入下面:
-module(tut).
-export([run/0).

run() ->
    io:format("Hello wrold~n",[]).

把这个文件保存为tut.erl(注意在Windows下面可以保存到werl的运行路径下面

)。
打开Erlang Shell。
1>c(tut).
{ok,tut}

2>tut:run().
Hello wrold
ok
3>

现在回到程序的第一行。
-module(tut).
每一个Erlang程序,都是一个module。这一行的意思是Module的名称是tut,这个

名称必须与文件的名称相同,如模块名称是tut,则文件名必须是tut.erl。当调

用模块里面的函数的时候,使用模块名称:函数名称(参数)来调用,如

tut:run().

第二行:
-export([run/0]).
表示模块输出的函数列表,tut里面输入的函数是run,0代表它的参数是0个。如

果输入多个函数,中间可以用","分割,譬如下面的程序tut2.erl:
-module(tut2).
-export([run/0,fac/1,mult/2]).

run() ->
    io:format("Hello wrold~n",[]).

fac(1) ->
    1;
fac(N) ->
    N*fac(N-1).

mult(X,Y) ->
    X*Y.
可以看到输出了三个函数run,fac和mult。
特别注意里面的fac的定义:
fac(1) ->
    1;
fac(N) ->
    N*fac(N-1)
注意在1的后面是一个";",代表函数还有其它定义。

1.3 Atom
atom是Erlang的一种数据类型。Atom只是一个名称而已,没有其它的含义。譬如

下面的程序,程序的功能是实现从公制与英制之间的转换。
-module(tut2).
-export([convert/2]).

convert(M, inch) ->
    M / 2.54;

convert(N, centimeter) ->
    N * 2.54.

编译一些,输出:
9> c(tut2).
{ok,tut2}
10> tut2:convert(3, inch).
1.18110
11> tut2:convert(7, centimeter).
17.7800
如果输入:
13> tut2:convert(3, miles).

=ERROR REPORT==== 28-May-2003::18:36:27 ===
Error in process <0.25.0> with exit value: {function_clause,

[{tut2,convert,[3,miles]},{erl_eval,expr,3},{erl_eval,exprs,4},

{shell,eval_loop,2}]}
** exited: {function_clause,[{tut2,convert,[3,miles]},
                             {erl_eval,expr,3},
                             {erl_eval,exprs,4},
                             {shell,eval_loop,2}]} **
可以看到由于其参数是"miles",而不是inch或者centimeter,所以会提示程序错

误。

1.4 Tuple
上面的程序里面:
tut2:convert(3, miles)

其中3的含义比较模糊,它到底是一个英制还是一个公分呢?Erlang提供一个一个

更加容易理解的方式,可以这样编写:

-module(tut3).
-export([convert_length/1]).

convert_length({centimeter, X}) ->
    {inch, X / 2.54};
convert_length({inch, Y}) ->
    {centimeter, Y * 2.54}.
   

编译运行:

14> c(tut3).
{ok,tut3}
15> tut3:convert_length({inch, 5}).
{centimeter,12.7000}
16> tut3:convert_length(tut3:convert_length({inch, 5})).
{inch,5.00000}

可以看到程序的含义就非常的明显了。Convert函数返回的就是一tuple。tuple可

以是更加复杂的声明,譬如:
{moscow, {c, -10}}
{cape_town, {f, 70}}
{paris, {f, 28}}

在{moscow, {c, -10}}里面,第一个元素是moscow,第二个元素是{c,-10}。

1.5列表
在Erlang里面,用"[]"来包含其元素,譬如:
[{moscow, {c, -10}}, {cape_town, {f, 70}}, {stockholm, {c, -4}},{paris,

{f, 28}}, {london, {f, 36}}]
一个比较实用的技巧是使用"|"来查看lists的元素,譬如:
18> [First |TheRest] = [1,2,3,4,5].
[1,2,3,4,5]
19> First.
1
20> TheRest.
[2,3,4,5]
用|来分割了[1,2,3,4,5],这样First的值是1,而TheRest的值是[2,3,4,5].
再尝试一个例子:
21> [E1, E2 | R] = [1,2,3,4,5,6,7].
[1,2,3,4,5,6,7]
22> E1.
1
23> E2.
2
24> R.
[3,4,5,6,7]
可以看到E1、E2、R三个变量得到了lists的不同部分。
利用这个技巧可以写一个计算lists长度的Module,譬如:
-module(tut4).

-export([list_length/1]).

list_length([]) ->
    0;   
list_length([First | Rest]) ->
    1 + list_length(Rest).

1.6标准Module和帮助
可以输入:
% erl -man io
ERLANG MODULE DEFINITION                                    io(3)

MODULE
     io - Standard I/O Server Interface Functions

DESCRIPTION
     This module provides an  interface  to  standard  Erlang  IO
     servers. The output functions all return ok if they are suc-
     ...
1.7输出到终端
可以利用io:io:format实现数据输出,譬如:
32> io:format("hello world~n", []).
hello world
ok
33> io:format("this outputs one Erlang term: ~w~n", [hello]).
this outputs one Erlang term: hello
ok
34> io:format("this outputs two Erlang terms: ~w~w~n", [hello, world]).
this outputs two Erlang terms: helloworld
ok
35> io:format("this outputs two Erlang terms: ~w ~w~n", [hello,

world]).
this outputs two Erlang terms: hello world
ok

1.8一个比较大的例子
现在有一些数据,代表世界上一些城市的温度,不过现在温度的表示格式不是非

常的统一,有的是用摄氏度标识,有的是以华氏摄氏度来表示,如何能够统一用

摄氏度来表示呢?看一下:
%% This module is in file tut5.erl

-module(tut5).
-export([format_temps/1]).

%% Only this function is exported
format_temps([])->                        % No output for an empty list
    ok;
format_temps([City | Rest]) ->
    print_temp(convert_to_celsius(City)),
    format_temps(Rest).

convert_to_celsius({Name, {c, Temp}}) ->  % No conversion needed
    {Name, {c, Temp}};
convert_to_celsius({Name, {f, Temp}}) ->  % Do the conversion
    {Name, {c, (Temp - 32) * 5 / 9}}.

print_temp({Name, {c, Temp}}) ->
    io:format("~-15w ~w c~n", [Name, Temp]).

36> c(tut5).
{ok,tut5}
37> tut5:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},
 {stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).
moscow          -10 c
cape_town       21.1111 c
stockholm       -4 c
paris           -2.22222 c
london          2.22222 c
ok

程序的功能应该还是比较简单明了。

1.9寻找最大或者最小值的程序
-module(tut6).
-export([list_max/1]).

list_max([Head|Rest]) ->
   list_max(Rest, Head).

list_max([], Res) ->
    Res;
list_max([Head|Rest], Result_so_far) when Head > Result_so_far ->
    list_max(Rest, Head);
list_max([Head|Rest], Result_so_far)  ->
    list_max(Rest, Result_so_far).
   

39> c(tut6).
{ok,tut6}
40> tut6:list_max([1,2,3,4,5,7,4,3,2,1]).
7

1.10  lists进阶
其实|还有更多的用法。
譬如:
50> [M1|T1] = [paris, london, rome].
[paris,london,rome]
51> M1.
paris
52> T1.
[london,rome]
|可以用来添加元素:
53> L1 = [madrid | T1].
[madrid,london,rome]
54> L1.
[madrid,london,rome]

下面是一个翻转lists的程序:
module(tut8).

-export([reverse/1]).

reverse(List) ->
    reverse(List, []).

reverse([Head | Rest], Reversed_List) ->
    reverse(Rest, [Head | Reversed_List]);
reverse([], Reversed_List) -&g 
原创粉丝点击