【Erlang】二、模块与函数

本文介绍了Erlang语言的基础知识,包括模块定义、函数声明、条件分支、列表处理等内容,并详细解释了如何使用fun类型进行高阶编程。

模块

基本代码单元,存于.erl的文件中,需被编译才能运行。编译后的模块以.beam作为扩展名

-module(geometry)		%模块声明:需与存放该模块的主文件名相同【例如本文件名应为geometry.erl】
-export([area/1])		%导出声明:Name/N	Name:函数名;N:元数(arity)	带有N个参数的函数Name可以在模块外使用

area([rectangle,Width,Height]) -> Width*Height;	
area({square,Side})			   -> Side*Side.

fun

在Erlang用于代表函数的数据类型为fun,是一种“匿名的”函数

1>Double = fun(X) -> 2*X end.
#Fun<erl_eval.6.99386804>
2>Double(9).
81
3>TempConvert = fun({c,C}) -> {f,32 + C*9/5};		%摄氏度转华氏度
3>				   ({f,F}) -> {c,(F-32)*5/9}		%华氏度转摄氏度
3>				end.    
#Fun<erl_eval.6.99386804>
4>TempConvert({c,100}).
{f,212.0}
5>TempConvert({f,212}).
{c,100.0}

以fun作为参数

标准库的lists模块中以fun作为参数的函数:

lists:map(F,L):给列表L中的各个元素应用fun F并返回列表

1>L =[1,2,3,4].
[1,2,3,4]
2>lists:map(fun(X)->2*X end,L).

lists:filter(P,L):返回L中所有符合条件的元素列表【对元素而言P(E)=true】

1>Even = fun(X) -> (X rem 2) =:= 0 end.	%=:=测试是否相等
#Fun<erl_eval.6.99386804>
2>lists:filter(Even,[1,2,3,4,5,6,7,8]).
[2,4,6,8]

返回fun的函数

1>Mult = fun(Times) -> ( fun(X) -> X * Times end ) end.
#Fun<erl_eval.6.99386804>
2>Triple = Mult(3).											%此时Triple为fun(X)-> X*3 end
#Fun<erl_eval.6.99386804>
3>Triple(5)
15

定义for循环

Erlang没有for循环,创建一个lib_misc.erl来自定义一个:

-module(lib_misc)
-export([for/3])
for(Max,Max,F) -> [F(Max)];
for(I,Max,F)   -> [F(I)|for(I+1,Max,F)].

编译后即可调用:

1>lib_misc:for(1,5,fun(X)->X*2 end). 
[2,4,6,8,10]

条件分支

关卡

通过关键字when可以在函数定义的头部使用关卡

max(X,Y) when X > Y -> X;
max(X,Y) -> Y.

X =:= dog; X =:= cat						%分号(;)的意思是“或者”
is_interger(X), X >Y ; abs(Y) < 23			%X是一个整数,且X>Y或者Y的绝对值小于23

关卡判定函数

判断函数意思
is_atom(X)X是一个原子
is_binary(X)X是一个二进制型
is_constant(X)X是一个常量
is_float(X)X是一个浮点数
is_function(X)X是一个fun
is_funtion(X,N)X是一个带有N个参数的fun
is_integer(X)X是一个整数
is_list(X)X是一个列表
is_map(X)X是一个映射组
is_number(X)X是一个整数或浮点数
is_pid(X)X是一个进程标识符
is_pmod(X)X是一个参数化模块的实例
is_port(X)X是一个端
is_reference(X)X是一个引用
is_tuple(X)X是一个元组
is_record(X,Tag)X是一个类型为Tag的记录
is_record(X,Tag,N)X是一个类型为Tag、大小为N的记录

关卡内置函数

函数意思
abs(X)X的绝对值
byte_size(X)X的字节数,X必须是一个位串或二进制型
element(X)X的元素N,X必须是一个元组
float(X)将X转为浮点数,X必须是一个数字
hd(X)列表X的表头
length(X)列表X的长度
node()当前节点
node(X)创建X的节点,X可以是一个进程、标识符、引用或者端口
round(X)将X转换成一个整数,X必须是一个数字
self()当前进程的进程标识符
size(X)X的大小,X可以是一个元组或者二进制型
trunc(X)将X去掉小数部位取整,X必须是一个数字
tl(X)列表X的表尾
tuple_size(T)元组T的大小

case

执行过程:

1.执行Expression,获得值Value。

2.Value与Pattern(带由可选的关卡Guard)一一匹配。

3.匹配成功则case的值为Expr_seq执行后的值。

4.若全不匹配,产生异常。

case Expression of
	Pattern1 [when Guard1] -> Expr_seq1;
    Pattern2 [when Guard2] -> Expr_seq2;
    ...
end

if

执行过程:

1.执行Guard1,若为true,则if的值为Expr_seq1的值。

2.若Guard1为false,继续执行Guard2直到某个关卡成功为止。

3.if表达式必须至少有一个关卡的执行结果为true,否则会产生异常。

大多时候if表达式的最后一个关卡是原子ture,确保其他关卡失败时表达式的最后部分会被执行。

if
	Guard1 ->
		Expr_seq1;
	Guard2 ->
		Expr_seq2;
	...
end

列表处理

列表推导

1>L = [1,2,3,4,5].
[1,2,3,4,5]
2>lists:map(fun(X) -> 2*X end, L).		%方法一:通过调用lists:map函数
[2,4,6,8,10]
3>[2*X || X <- L].						%方法二:列表推导(list comprehension)
[2,4,6,8,10]

[ F(X) || X <- L ]:由F(X)组成的列表【X从列表L中提取】

[ X*2 || X <- L ]:由2*X组成的列表【X从列表L中提取】

构建自然顺序的列表

高效:

some_function([H|T] , ..., Result, ... ) ->
	H1 = ... H ...,									%从输入列表的头部提取元素
	some_function(T , ..., [H1|Result], ... );		%总是向表头添加元素
some_function([], ..., Result, ...) ->
	{..., Result, ...}

​ 最后的输出列表的元素顺序会与原始列表的元素顺序相反,此时仅需使用lists:reverse即可将顺序反转过来。

低效:List ++ [H]

内置函数

BIF(built-in function),作为Erlang语言定义一部分的函数。有些由Erlang实现,大多数是用Erlang虚拟机里的底层操作实现。可提供操作系统的接口。

将列表转为元组:list_to_tuple,查询时间time()…

可通过该网址查看:http://www.erlang.org/doc/man/erlang.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值