Erlang 程序设计 学习笔记(二) 模块与函数

Erlang 程序设计 学习笔记(二) 模块与函数

模块与函数

模块是Erlang的基本代码单元,模块保存在扩展名为.erl的文件里,编译后的模块以.beam作为扩展名

先来看一个模块的代码geometry.erl

%% @author DaDa
%% @doc @todo Add description to geometry.


-module(geometry).

%% ====================================================================
%% API functions
%% ====================================================================
-export([test/0,area/1]).

test()->
	6 = area({rectangle,2,3}),
	4 = area({square,2}),
	test_ok.

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



%% ====================================================================
%% Internal functions
%% ====================================================================



-moudle(geometry).
模块声明:  声明里的模块名必须与存放该模块的主文件名相同



-export([tesr/0 , area / 1]).
导出声明:  Name/N这种记法是指一个带有N个参数的函数Name,N被称为函数的元
数(arity)。export的参数是由Name/N项目组成的一个列表。因此,-export([area/1])的意思
是带有一个参数的函数area可以在此模块之外调用。


子句:  area函数中有两个子句 ,子句没有固定的顺序, 调用函数时会从第一个与调用参数相匹
配的子句开始执行



再看一个模块

%% @author DaDa
%% @doc @todo Add description to shop.


-module(shop).

%% ====================================================================
%% API functions
%% ====================================================================


-export([cost/1,total/1]).

%%返回每类物品的单价
cost(oranges) -> 5;
cost(newspaper)->8;
cost(pears) -> 2;
cost(milk) -> 9;
cost(apples) -> 7.

%%计算总共价值
total([{What,N}|T])-> cost(What) * N + total(T);
total([])->0.

%% ====================================================================
%% Internal functions
%% ====================================================================

函数遍历某个列表

total/1函数用于计算传递里列表中所有商品的总价格

例如shop::total([{pears,6},{milk,3}]).

1: cost(pears) * 6 + total([{milk,3}])

2:12+cost(milk)*3 + total[]

3:12+27+0;

4:39

fun 基本的抽象单元

Erlang是一种函数式编程语言。此外,函数式编程语言还表示函数可以被用作其他函数的参
数,也可以返回函数。操作其他函数的函数被称为高阶函数(higher-order function),而在Erlang
中用于代表函数的数据类型被称为fun

可以将一个函数直接指派给某个变量

1> MyAdd = fun(X , Y)->X + Y end.
#Fun<erl_eval.12.80484245>
2> MyAdd(1,222).
223


以fun作为参数的函数

标准库里的lists模块导出了一些以fun作为参数的函数。它们之中最有用的是lists:map(F,
L)。这个函数返回的是一个列表,它通过给列表L里的各个元素应用fun F生成。

1> L = [1,2,3,4].
[1,2,3,4]
2> MyDouble = fun(X)->2 * X end.
#Fun<erl_eval.6.80484245>      
3> lists:map(MyDouble,L).
[2,4,6,8]
4> 

返回fun的函数

7> Mult = fun(Times) ->(fun(X)->X * Times end)end.
#Fun<erl_eval.6.80484245>
8> Mult(3).
#Fun<erl_eval.6.80484245>
9> Triple = Mult(3).
#Fun<erl_eval.6.80484245>
10> Triple(2).
6
11> Double = Mult(2).
#Fun<erl_eval.6.80484245>
12> Double(23).
46
13> 

在这里Double 和 Triple 最为返回fun的函数所指派的对象,即Double 和 Triple分别是两个函数 Mult(2)  和 Mult(3)

Mult(2)函数会将传递过来的数字乘以Times


列表推导

[ F(X) || X <- L]标记的意思是“由F(X)组成的列表(X从列表L中提取)”。因此,[2*X|| X <- L ]的意思就是“由2*X组成的列表(X从列表L中提取)”。

1> L = [1,2,3,4,5,6].
[1,2,3,4,5,6]
2> lists:map(fun(X)->X * 2 end , L).
[2,4,6,8,10,12]
3> [X*2||X<-L].
[2,4,6,8,10,12]
4> 

内置函数

list_2_tuple/1  将一个列表转换成元组

time/0以{时,分,秒}的格式返回当前的时间。


关卡

关卡(guard)是一种结构,可以用它来增加模式匹配的威力。通过使用关卡,可以对某个模式里的变量执行简单的测试和比较
-module('max').


-export([max/2]).

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

true关卡
原子true可以被当作“来者不拒”的关卡,放置在某个if表达式的最后


关卡判断函数

函数 意思
abs(X) X的绝对值
byte_size(X)  X的字节数,X必须是一个位串或二进制型
element(N, 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的大小,它可以是一个元组或二进制型
trunc(X) 将X去掉小数部分取整,X必须是一个数字
tl(X) 列表X的列表尾
tuple_size(T) 元组T的大小
is_atom(X) X是一个原子
is_binary(X) X是一个二进制型
is_constant(X) X是一个常量
is_float(X) X是一个浮点数
is_function(X) X是一个fun
is_function(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的记录











































case和if表达式

case语法
case Exoressuib of 
Pattern1 [when Guard1] -> Expr_seq1;
Pattern1 [when Guard1] -> Expr_seq1;
...
end
case的执行过程如下:首先,Expression被执行,假设它的值为Value。随后,Value轮流
与Pattern1(带有可选的关卡Guard1)、Pattern2等模式进行匹配,直到匹配成功。一旦发现
匹配,相应的表达式序列就会执行,而表达式序列执行的结果就是case表达式的值。如果所有模
式都不匹配,就会发生异常错误(exception)。

if语法
if
Guard1 -> 
Expr_seq1;
Guard2 -> 
Expr_seq2;
...
end
首先执行Guard1。如果得到的值为true,那么if的值就是执行表达式
序列Expr_seq1所得到的值。如果Guard1不成功,就会执行Guard2,以此类推,直到某个关卡
成功为止。if表达式必须至少有一个关卡的执行结果为true,否则就会发生异常错误。
很多时候,if表达式的最后一个关卡是原子true,确保当其他关卡都失败时表达式的最后
部分会被执行




你可能感兴趣的:(Erlang 程序设计 学习笔记(二) 模块与函数)