Erlang 中的递归
今天看了看Erlang编程指南,发现其中的递归还是挺有特色的,递归式函数式编程语言的一大特色了。
递归
比如一个求平均数的例子:
1 average(List) -> sum(List) / len(List). 2 3 sum([]) -> 0;
4 sum([Head | Tail]) -> Head + sum(Tail). 5 len([]) -> 0;
6 len([_ | Tail) -> 1 + len(Tail).
先看sum函数,sum([])->0. 如果列表是空的,那么元素总和是零
sum([Head | Tail]) -> Head + sum(Tail). 如果至少包含一个元素,那么把它分解成头部和尾部,总和就是头部与尾部的和
len函数也同样,由于len只关心个数所以使用了"_",表示头部的值是无关紧要的
筛选出列表中所有的偶数:
1 even([]) -> []; 2 even([Head | Tail]) when Head rem 2 == 0 -> [Head | even(Tail)]; 3 even([_ | Tail]) -> even(Tail).
这里第二个even使用了保护元(guard)来提供执行函数的前提条件。
判断列表中是否有指定元素:
1 member(_, []) -> false; 2 member(H, [H | _]) -> true; 3 member(H, [_ | T]) -> member(H, T).
尾递归
尾递归就是调用者在函数的最后调用自己,即不需要保存调用者的堆栈信息,相较于普通递归,更省内存,效率更高。
sum的尾递归版本:
1 sum_acc([], Sum) -> Sum; 2 sum_acc([Head | Tail]), Sum) -> sum_acc(Tail, Head + Sum).
如下调用:
sum(List) -> sum_acc(List, 0).

浙公网安备 33010602011771号