1.模块
- 1)在erlang中定义函数,在未编译前后缀名为.erl,编译后后缀名为.beam
- 2)以geometry.erl模块为例,首先使用pwd(),显示出编译时所在的目录,如本机显示为D:/Erlang/erl7.3/usr ,故在该目录下,新建txt文件并修改后缀名为.erl,并输入内容:
-module(geometry). -export([area/1]). area({rectangle,Width,Height}) ->Width*Height; area({square,Side}) ->Side*Side.
2.函数
- 1)在编译器中运行 c(geometry). 然后就可以进行调用area()函数:
-
1>geometry:area({rectangle,10,5}). 50 2>geometry:area({square,3}). 9
3.模块代码内加测试
- 1)给代码添加测试,在定义模块时,可以内置test代码,具体如下:
-
-module(geometry1). -export([test/0,area/1]). test()-> 12=area({rectangle,3,4}), 144=area({square,12}), tests_worked. area({rectangle,Width,Height}) ->Width*Height; area({square,Side}) -> Side*Side.
4.在一个模块中对另一个模块进行调用,并实现迭代list
- 在一个模块中调用另一个模块的函数,配合list中的[头|尾]的方式,可以实现对list中的数据的迭代遍历.
- 如:定义一个模块shop.erl
-module(shop). -export([cost/1]). cost(oranges) ->5; cost(nespaper) ->8; cost(apples) ->2; cost(pears) ->9; cost(milk) ->7.
- 然后再定义一个shop1.erl,内容如下:
-
-module(shop1). -export([total/1]). total([{What,N}|T]) ->shop:cost(What)*N + total(T); total([]) ->0.
-
当输入 shop1:total([]). 时,输出结果为0; 当输入shop1:total([{milk,3}]). 时,输出结果为21,注意,此时T=[], 当输入shop1:total([{milk,3},{oranges,4}]). 时,输出结果为41,T1=[{oranges,4}],T2=[].
5.fun:基本的抽象单元,用于代表函数的数据类型
1>Double=fun(X) -> 2*X end.
#Fun<erl_eval.6.50752066>
2>Double(2).
4
3>Hypot=fun(X,Y) -> math:sqrt(X*X+Y*Y) end.
#Fun<erl_eval.12.50752066>
4>Hypot(3,4).
5.0
5> TempConvert=fun({c,C}) ->{f,32+C*9/5};
5> ({f,F}) ->{c,(F-32)*5/9}
5> end.
#Fun<erl_eval.6.50752066>
6> TempConvert({c,100}).
{f,212.0}
7> TempConvert({f,100}).
{c,37.7777777777778}
6.以fun作为参数的函数
Erlang的标准库中lists模块导出了一些以fun作为参数的函数,有list:map(F,L)和lists:filter(P,L),lists:member(X,L)
- 1)lists:map(F,L):为列表L里的各个元素应用F生成.
1>L=[1,2,3,4]. 2>lists:map(fun(X) -> 2*X end,L). [2,4,6,8]
- 2)lists:filter(P,L):返回一个新的列表,内含L中所有符合条件的元素(条件时对元素E而言P(E)为true.
应用: 1>Even=fun(X) ->(X rem 2) =:=0 end. %% X rem 2表示求X除以2后的余数,=:=用来测试是否相等. 2>Even(8). true 3>Even(7). false 4>lists:map(Even,[1,2,3,4,5,6,7,8]). [false,true,false,true,false,true,false,true] 5>lists:filter(Even,[1,2,3,4,5,6,7,8]). [2,4,6,8].
- 3)lsits:member(X,L):如果X是列表L中的成员,则返回true,否则返回false
1>Fruit=[apple,pear,orange]. 2>MakeTest=fun(L) ->(fun(X) ->lists:member(X,L) end) end. %%注意:MakeTest传入的第一个参数给了fun(L),然后进入fun(X)等待传值期 3>IsFruit=MakeTest(Fruit). %%将已经接收L参数后的MakeTest的指引给予IsFruit,所以IsFruit=fun(X) ->lists:member(X,L) end 4>IsFruit(pear). true 5>lists:filter(IsFruit,[dong,orange,cat,apple,bear]). [orange,apple]
7.自定义控制抽象
- 1)实现for循环.
-module(lib_misc). -export([for/3]). for(Max,Max,F) ->[F(Max)]; for(I,Max,F) ->[F(I)|for(I+1,Max,F)]. %%利用头|尾的方法进行遍历 1>c(lib_misc). 2>lib_misc:for(1,10,fun(I) ->I end). [1,2,3,4,5,6,7,8,9,10]
- 2)实现sum方法
-module(mysum). -export([sum/1]). sum([H|T]) ->H+sum(T); sum([]) ->0. 1>c(mysum). 2>mysum:sum([1,2,3,4,5]. 15
- 3)实现map方法
-module(mymap). -export([map/2]). map(_,[]) ->[]; map(F,[H|T]) ->[F(H)|map(F,T)]. 1>c(mymap) 2>mymap:map(fun(X) ->X*X end,[1,2,3,4,5]). [1,4,9,16,25]
8.列表推导
列表推导常规的形式:[X || Qualifier1,Qualifier2,....]X是任意一条表达式,后面的限定符(Qualifier)可以是生成器,位串生成器或过滤器.生成器的写法是:Pattern <-ListExpr ,其中的ListExp必须是一个能够得出列表的表达式位串生成器的写法是:BitStringPattern <= BitStringExpr ,其中的BitStringExpr必须是一个能够得出位串的表达式过滤器既可以是判断函数(即返回true或false的函数),也可以是布尔表达式.
1>[2*X || X<-[1,2,3,4]].
[2,4,6,8]
2>[X|| {a,X} <-[{a,1},{b,2},{c,3},{a,4},hello,"wow"]].
[1,4]
%%应用的是过滤器
%%实现快速排序算法
-module(quicksort).
-export([sort/1]).
sort([]) ->[];
sort([H|T]) ->
sort([X || X<-T , X<H]) ++ [H] ++ sort([X || X<-T,X>=H]).
%%注意++的作用是字符连接
%%该算法将T分为两部分,一部分小于H,一部分大于H,然后再循环调用.
1>quicksort:sort([3,61,1,8,22,754,35,36,36,90,34]).
[1,3,8,22,34,35,36,36,61,90,754]
%%毕达哥拉斯三元数组
-module(lasi).
-export([pythag/1]).
pythag(N) ->
[{A,B,C} ||
A <-lists:seq(1,N), %lists:seq实现对1到N的遍历
B <-lists:seq(1,N),
C <-lists:seq(1,N),
A+B+C=<N, %注意=<符号
A*A+B*B =:=C*C %注意=:= 符号
].
%%回文构词
-module(perms).
-export([perms/1]).
perms([]) -> [[]];
perms(L) -> [[H|T] || H<- L,T<- perms(L--[H])]. %--的作用是从L中删除H
9.内置函数
- list_to_tuple:将一个列表转变成元组
- time() :得出现在的时分秒
10.关卡
- 1)when
- f(X,Y) when is_integer(X), X>Y ,Y<6 -> ..... 表示当X是一个整数,X大于Y且Y小于6时
- 2)and andalso or orelse xor not
- and 如果两个参数都是真,那么就返回真
- andalso and的快捷计算,第一参数为假,则返回假,不需要计算第二个参数
- or 如果两个参数任一个为真,则返回真
- orelse or的快捷计算,第一参数为真,就返回真,不需计算第二个参数
- xor 异或
- not 否定运算
- 3)true关卡
- if Guard -> Ex; Guard1 ->Ex1; ........ true -> Ex ; 相当于finally
- 4)case
- case Expression of
- Pattern1 -> Ex1;
- Pattern2 -> Ex2;
- .....
- end.
- 5)if
- if
- Guard1 -> Ex1;
- Guard2 -> Ex2;
- ......
- end
11.构建自然顺序的列表:最有效率的方法是向某个现成列表的头部插入元素
12.归集器的实现
%%以分奇数偶数为例
odds_and_evens2(L) ->
odds_and_evens_acc(L,[],[]).
odds_and_evens_acc([H|T],Odds,Evens) ->
case (H rem 2) of
1 -> odds_and_evens_acc(T,[H|Odds],Evens);
0 -> odds_and_evens_acc(T,Odds,[H|Evens])
end;
odds_and_evens_acc([] ,Odds,Evens) ->
{Odds,Evens}.