在Erlang语言中,为了提高运行效率,少占用系统资源,在编写递归调用的函数中,主要分为两类:非尾递归和尾递归。
尾递归是指在递归函数的内部进行递归调用时,在递归调用之后函数就结束了。以下以两个简单的例子作为说明:
1.使用非尾递归编写求0-X的数值之和
sum(0) ->
0;
sum(X) ->
sum(X-1) + X.
当传入3时,递归调用流程如下:
sum(3-1) + 3
sum(2-1) + 2
sum(1-1) +1
sum(0)
每一步调用,则深入一层,直至调用sum(0)返回0,最后才能计算出结果6。
2.使用尾递归编写求0-X的数值之和
使用尾递归编写求0-X的数值之和定义的函数如下:
sum(X) ->
sum(X,0).
sum(0,S) ->
S;
sum(X,S) ->
sum(X-1,S+X).
以上实际定义了两个函数。虽然它们的名字都是sum,但其参数的个数不同,在Erlang中视为“同名不同目”的函数,是完全不同的两个函数。
当调用sum(3)时,会转到调用函数sum(3,0),此时第二个函数会得到执行。
第一次执行之后会调用sum(3-1,0+3),即sum(2,3);
第二次执行之后会调用sum(2-1,3+2),即sum(1,5);
第三次执行之后会调用sum(1-1,5+1),即sum(0,6);
第四次执行之后直接返回了6,即为正确的结果。