打印列表中的所有项目

时间:2017-06-10 14:07:48

标签: list recursion erlang

我最近开始做一些真正基本的Erlang开发,因为他们没有触及该语言大约五年。

我无法理解为什么我的函数似乎在递归中无休止地循环:

-module(list_tut).
-export([print_cities/1]).
-author("kimput").

print_cities([]) ->
  ok;

print_cities([H|T]) ->
  io:format('city: ~p~n', [H]),
  [H|print_cities([T])]. 

如果我输入的城市列表如下:

> list_tut:print_cities(['Moscow', 'Tokyo', 'Stockholm']).

它会相当快速地打印所有项目,然后继续打印cities: []

我知道这是一个绝对的初学者问题,但我现在已经看了很长时间这个问题并且无法在不添加尾递归的情况下找到解决它的方法或类似的东西...

任何建议都会受到很大的关注! :)

1 个答案:

答案 0 :(得分:2)

这是因为您使用[T]而不是T进行了递归。 T是列表的尾部,它已经是一个列表(如果列表不是不正确的列表)。你的代码将尾部包装在另一个列表中,这意味着除了无限递归之外,打印的初始元素也是错误的:

1> c(list_tut).
{ok,list_tut}
2> list_tut:print_cities(['Moscow', 'Tokyo', 'Stockholm']).
city: 'Moscow'
city: ['Tokyo','Stockholm']
city: []
city: []
city: []
city: []
city: []
...

[H|print_cities([T])].更改为[H|print_cities(T)].可解决此问题:

-module(list_tut).
-export([print_cities/1]).
-author("kimput").

print_cities([]) ->
  ok;

print_cities([H|T]) ->
  io:format('city: ~p~n', [H]),
  [H|print_cities(T)].
1> c(list_tut).
{ok,list_tut}
2> list_tut:print_cities(['Moscow', 'Tokyo', 'Stockholm']).
city: 'Moscow'
city: 'Tokyo'
city: 'Stockholm'
['Moscow','Tokyo','Stockholm'|ok]

我不确定你为什么要在打印函数中重新创建列表,但是如果你想要原始列表,如果你想要最终的返回值,那么[]的情况应该返回[]与最初的一样。

...
print_cities([]) ->
  [];
...
1> c(list_tut).
{ok,list_tut}
2> list_tut:print_cities(['Moscow', 'Tokyo', 'Stockholm']).
city: 'Moscow'
city: 'Tokyo'
city: 'Stockholm'
['Moscow','Tokyo','Stockholm']