Erlang顺序编程(一)模块(module):module是erlang中代码的基本单元,所有函数都位于模块之中,模块文件一般存
Erlang顺序编程(一)
模块(module):
module是erlang中代码的基本单元,所有函数都位于模块之中,模块文件一般存放在.erl文件中。
要运行一个模块,首先要先编译它,编译成功之后会生成一个.beam的文件。
模块名与文件名一致
-module(test2).-export([area/1]).area({rectangle,Width,Ht}) ->Width*Ht;area({circle,R}) ->3.14*R*R.调用:
c(test2). //编译文件test2:area({circle,5}). //调用test2模块的area函数。查看自己当前的工作区间:pwd().
Erlang中三种标点符号:逗号,句号,分号。
逗号:用来分隔函数的调用,数据构造器,以及模式中的参数。
句号:用来分隔一条完整的函数或表达式。
分号:用来分隔子句。
函数的目就是拥有的参数数量,在erlang中同一模块的两个函数,名字相同,目不同,他们是不同的两个函数。
fun:匿名函数。
Z=fun(X) -> 2*X end.
调用
Z(2).
fun可以拥有任意数量的参数。
hypot = fun(X,Y) -> math:sqrt(X*X+Y*Y) end.
调用
Hypot(3,4).
fun可以有若干不同的子句。
Temp = fun({c,C}) -> {f,32+C*9/5}; ({f,F}) -> {c,(F-32)*9/5} end.调用
Temp(c,100).
fun可以作为函数的参数使用。
lists:map(F,L):这个函数将fun F应用到列表L的每一个元素上,返回一个新的列表。
Double = fun(X) -> X*2 end.L=[1,2,3,4].lists:map(Double,L).//[2,4,6,8]
lists:filter(F,L):返回一个新列表,新列表由列表L中每一个能满足F(E)为true的元素组成。
P=fun(X) -> (X rem 2)=:=0 end.lists:filter(P,L).//[2,4]
=:=是一个恒等测试符号。
fun可以作为函数的返回值。
Fruit=[apple,pear,orange].MakeTest=fun(L)->(fun(X)->lists:member(X,L) end) end.IsFruit = MakeTest(Fruit).IsFruit(pear).//true
lists:member(X,L):判断X是不是列表L的元素,如果是返回true,否则false.
erlang中没有for循环。
-module(for).-export([for/3]).for(Max,Max,F) ->[F(Max)];for(I,Max,F) ->[F(I)|for(I+1,Max,F)].
列表解析:列表解析是一种无需使用fun,map,filter来创建列表的表达式。
例如:我们想让列表里面的每个元素加倍。以前的做法是
Lists:map(fun(X) -> 2*X end,L).
列表解析的做法:
[2*X||X<-L].
[F(X)|X<-L]代表“由F(X)组成的列表,其中X是取值于列表L”。
列表解析的常见形式:
[X||Qua1,Qua2,….]
X可以是任意表达式。每个限定词(Qua)可以是一个生成器或者是一个构造器。生成器通常形式:Pattern<-ListExpr。
排序算法:
-module(sort).-export([sort/1]).sort([P|T]) -> sort([X||X<-T,X<P]) ++ [P] ++ sort([X||X<-T,X>=P]);sort([]) ->[].
++是一个中缀添加操作符。
比格拉斯三元组:
-module(pythag).-export([pythag/1]).pythag(N) -> [ {A,B,C}|| A<-lists:seq(1,N), B<-lists:seq(1,N), C<-lists:seq(1,N), A+B+C =< N, A*A+B*B =:= C*C ].lists:seq(1,N):返回一个由1-N的整数列表。
guard:一种用于强化模式匹配功能的结构。
例子:比较两个数的最大值。
max(X,Y) when X>Y ->X;max(X,Y) ->Y.
在函数定义的头部使用guard,必须以when开头,也可以在任意表达式的地方使用guard,当guard用于表达式的时候,它被要求值为一个原子true或false。
guard序列可以是单个guard,也可以是一系列用分号分开的guard,在guard集合G1;G2;G3…;Gn中,只要任何一个guard为true,整个guard序列就为true。
guard也可以是一系列的用逗号分开的guard集合,guard集合G1,G2,G3…,Gn中,只有所有guard都为true时,整个guard序列才为true。
guard谓词:
is_atom(x):x是原子。
is_binary(X):X是二进制数据。
is_constant(X):X是常数。
is_float(X):X是浮点数。
is_function(X):X是函数。
is_function(X,N):X是有N个参数的函数。
is_integer(X):X是整数。
is_list(X):X是列表。
is_number(X):X是整数或者浮点数。
is_pid(X):X是进程标识符。
is_port(X):X是端口。
is_reference(X):X是引用。
is_tuple(X):X是元祖。
is_record(X,Tag,N):X是标记为Tag大小的N的记录。
is_record(X,Tag):X是标记为Tag大小的记录。
断言BIF(内置函数):
abs(X):X的绝对值。
element(N,X):元祖X的第N个元素。
float(X):将数字X转换为浮点数。
hd(X):列表X的头部。
length(X):列表X的长度。
node():当前节点。
node(X):创建X节点,X可以是进程标识符,引用或者端口。
round(X):对数字X进行四舍五入。
self():当前进程的进程标识符。
size(X):X的大小,X为元祖或者二进制数据。
trunk(X):将数字X转换为整数(截取)。
tl(X):列表X的尾部。
记录(record):记录提供了一种方法把一个名称与元祖中的一个元素对应起来。
定义语法:
-record(Name,{key1=Default1,key2=Default2,…}).Name是记录的名字,key1,key2等是记录中的字段名,这些名字都必须是原子,记录中的每个字段都可以有默认值。如果在创建的时候,没有为某个特定字段指定值,那么就会使用默认值。
-record(todo,{status=reminder,who=come,text}).一旦定义了记录,就能创建记录的实例。
X=#todo{}.X1=#todo{status=aaa,who=come,text=aaa}.X2=X1#todo{status=bbb}.记录只是元祖的伪装,记录就是元祖。
rf(todo):告诉shell释放掉todo这个记录的定义。