Erlang中的函数调用方式.

Posted 程序大官猿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Erlang中的函数调用方式.相关的知识,希望对你有一定的参考价值。

1:在Erlang中,【名字相同但参数数目不同】的两个函数是完全不同的函数。


2:其他模块内的函数用完全限定名称被调用:


-module(sort1).


-export([reverse_sort/1, sort/1]).

reverse_sort(L) ->


        lists1:reverse(sort(L)).

sort(L) ->


        lists:sort(L).


3.当同一个模块有2个版本被加载里,所有的local call都可以工作在当前版本状态,但是:external call只能调用到最新的版本!


(1) 使 用 Fun 的 场 景:


1.1 先启动1个shell终端,分别名为test1:

erl -name test1


1.2 test1加载模块mfa_test.erl.

-module(mfa_fun).-export([cal/2,func/0]). cal(X,Y) ->     X+Y.func() ->       

fun(X,Y) -> cal(X,Y) en


1.3在shell中输入:

>Func = mfa_fun:func(). #Fun<mfa_fun.1.52492151> >Func(1,2).3 


(2)使用MFA的场景:


改变mfa_test.erl中cal函数并重新加载这个模块:

cal(X,Y) -> X*Y .


1.5 再运行:

>Func(1,2).


可以看到这个Func运行的local版本,如果把func改为以下版本:

func() -> fun(X,Y) -> ?MODULE:cal(X,Y) end


总之:Erlang函数有local call和external call的区别,Local call 就是在函数在被定义的模块里面被调用,可以直接被调用: Func(Args); External call 就是显式的使用Module:Func(Args)来调用或import别的模块进来的调用.


3:子句间以分号【;】分隔,在最后的结尾处以【.】结尾。


4:每个函数都由一组子句组成。子句间以分号“;”分隔。每个子句都包含一个子句头部、一个可选的保护式和子句主体。子句的头部包含一个函数名和一组以逗号分隔的参数当函数调用发生时,将会按顺序对函数定义中的子句头部依次进行匹配。对保护式求值时所有的断言都将被求值。若所有断言都为真,则保护式成立,否则就失败。保护式中各个断言的求值顺序是不确定的。


如果保护式成立,则会对子句的主体进行求值。如果保护式失败,则尝试下一个候选子句。一旦子句的头部和保护式都匹配成功,系统将指定这条子句并对其主体求值。子句首部模式与保护式的组合可以唯一确定一个正确的子句。


保护式断言的完整集合如下:


保护式

成立条件

atom(X)

X 是一个原子式

constant(X)

X 不是列表或元组

float(X)

X 是一个浮点数

integer(X)

X 是一个整数

list(X)

X 是一个列表或 []

number

X 是一个整数或浮点数

pid(X)

X 是一个进程标识符

port(X)

X 是一个端口

reference(X)

X 是一个引用

tuple(X)

X 是一个元组

binary(X)

X 是一段二进制数据



另外,一些BIF和算术表达式的组合也可以作为保护式。它们是:

代码如下:


element/2, float/1, hd/1, length/1, round/1, self/0, ze/1


trunc/1,   tl/1, abs/1, node/1, node/0, nodes/0


可以出现在保护式中的项式比较运算符如下:


运算符

描述

类型

X > Y

X 大于Y

coerce

X < Y

X 小于Y

coerce

X =< Y

X 小于或等于Y

coerce

X >= Y

X 大于或等于Y

coerce

X == Y

X 等于Y

coerce

X /= Y

X 不等于Y

coerce

X =:= Y

X 等于Y

exact

X =/= Y

X 不等于Y

exact


比较运算符工作机制如下:首先对运算符两边求值(如,在表达式两边存在算术表达式或包含BIF保护式函数时);然后再进行比较。


为了进行比较,定义如下的偏序关系:


number < atom < reference < port < pid < tuple < list


元组首先按大小排序,然后再按元素排序。列表的比较顺序是先头部,后尾部。


如果比较运算符的两个参数都是数值类型且运算符为coerce型,则如果一个参数是integer另一个是float,那么integer将被转换为float再进行比较。


exact类型的运算符则不做这样的转换。


因此5.0 == 1 + 4为真,而5.0 =:= 4 + 1为假。
保护函数子句示例:


foo(X, Y, Z) when integer(X), integer(Y), integer(Z), X == Y + Z ->


foo(X, Y, Z) when list(X), hd(X) == {Y, length(Z)}  ->


foo(X, Y, Z) when {X, Y, size(Z)} == {a, 12, X} ->


foo(X) when list(X), hd(X) == c1, hd(tl(X)) == c2 ->


注意在保护式中不可引入新的变量。

以上是关于Erlang中的函数调用方式.的主要内容,如果未能解决你的问题,请参考以下文章

从 shell 脚本调用 erlang 文件的函数

erlang函数调用乱序?

为啥 erlang spawn 函数调用中出现语法错误 - “之前的语法错误:')'”?

为什么语法错误会出现在erlang spawn函数调用中 - “语法错误之前:')'”?

Erlang堆栈跟踪中包含多少条目?

Erlang:用新功能“扩展”现有模块