名单

这里是列表类型最简单的递归函数。此功能仅从开始到结束导航到列表,不再执行任何操作。

-spec loop(list()) -> ok.
loop([]) ->
  ok;
loop([H|T]) ->
  loop(T).

你可以这样称呼它:

loop([1,2,3]). % will return ok.

这里的递归函数扩展:

loop([1|2,3]) ->
  loop([2|3]) ->
    loop([3|]) ->
      loop([]) ->
        ok.

使用 IO 操作的递归循环

以前的代码什么都不做,而且没用。因此,我们现在将创建一个执行某些操作的递归函数。此代码类似于 lists:foreach/2

-spec loop(list(), fun()) -> ok.
loop([], _) ->
  ok;
loop([H|T], Fun) 
  when is_function(Fun) ->
    Fun(H),
    loop(T, Fun).

你可以像这样调用它:

Fun = fun(X) -> io:format("~p", [X]) end.
loop([1,2,3]).

这里的递归函数扩展:

loop([1|2,3], Fun(1)) ->
  loop([2|3], Fun(2)) ->
    loop([3|], Fun(3)) ->
      loop([], _) ->
        ok.

你可以比较 lists:foreach/2 输出:

lists:foreach(Fun, [1,2,3]).

递归循环列表返回修改后的列表

另一个有用的例子,类似于 lists:map/2 。此函数将采用一个列表和一个匿名函数。每次匹配列表中的值时,我们都会对其应用函数。

-spec loop(A::list(), fun()) -> list().
loop(List, Fun) 
  when is_list(List), is_function(Fun) ->
    loop(List, Fun, []).

-spec loop(list(), fun(), list()) -> list() | {error, list()}.
loop([], _, Buffer) 
  when is_list(Buffer) ->
    lists:reverse(Buffer);
loop([H|T], Fun, Buffer) 
  when is_function(Fun), is_list(Buffer) ->
    BufferReturn = [Fun(H)] ++ Buffer,
    loop(T, Fun, BufferReturn).

你可以这样称呼它:

Fun(X) -> X+1 end.
loop([1,2,3], Fun).

这里的递归函数扩展:

loop([1|2,3], Fun(1), [2]) ->
  loop([2|3], Fun(2), [3,2]) ->
    loop([3|], Fun(3), [4,3,2]) ->
      loop([], _, [4,3,2]) ->
        list:reverse([4,3,2]) ->
          [2,3,4].

这个函数也称为尾递归函数,因为我们使用像累加器这样的变量来通过多个执行上下文传递修改过的数据。