List 打印列表时,Erlang shell将冻结
我在打印列表时遇到了一个毫无头绪的问题。 这个程序编译得很好,但当我运行它时,编译器卡住了,无法处理。以下是代码片段:List 打印列表时,Erlang shell将冻结,list,erlang,List,Erlang,我在打印列表时遇到了一个毫无头绪的问题。 这个程序编译得很好,但当我运行它时,编译器卡住了,无法处理。以下是代码片段: print([]) -> []; print([H|T]) -> [H]++print([T]). 我将列表分为正面和反面,因为稍后我计划在其中实现更多操作。所以在此之前,我只想测试是否可以打印一个列表作为用户输入 我总是从一开始就将函数声明为[print/1]。也许我在别的地方搞砸了,所以请指出。发生这种情况是因为在递归调用之前,您将尾部包装到了一个列表中。将
print([]) -> [];
print([H|T]) -> [H]++print([T]).
我将列表分为正面和反面,因为稍后我计划在其中实现更多操作。所以在此之前,我只想测试是否可以打印一个列表作为用户输入
我总是从一开始就将函数声明为
[print/1]
。也许我在别的地方搞砸了,所以请指出。发生这种情况是因为在递归调用之前,您将尾部包装到了一个列表中。将print([T])
更改为print(T)
,它就会工作
让我们看看为什么会发生这种情况。考虑调用<代码>打印([ 42 ])< /> >,只是一个元素来保持这个简单。由于列表在Erlang中的工作方式,可以将其写成[42 |[]]
,意思相同
因此我们找到了子句print([H | T])
,H
是42,而T
是[]
。递归调用是print([T])
,其结果是print([]])
(一个包含一个空列表作为其唯一元素的列表)
正如我们所知,
[[]]
可以写成[[[].[]]
。因此,递归调用再次进入print([H | T])
子句,而不是我们预期的print([])
子句。现在,H
是[]
,T
是[]
。递归调用print([T])
变为print([]])
。。。我们有一个无限循环。这是无限递归首先要使代码可编译。因为现在不是。除了最后的print[T]
应该是print(T)
,这个代码没有任何问题,如图所示。你可以在贝壳里尝试类似的东西;运行:F=funf([])->[];F([H | T])->[H]++F(T)end,F(列表:seq(1,5))。
将按预期返回[1,2,3,4,5]
。所以,在我们帮助您之前,您需要向我们展示您的print/1
函数的功能。@Lol4t0就像我说的,如果print[T]
更改为print(T)
,就可以了。你试过了吗?我做到了,而且成功了。如果改为打印([T]),那么这就是无限递归的来源。@SteveVinoski是的,我把代码中的[H]++print[T]
搞砸了实际上我在我的代码中写了“代码>打印([Hyt])> [H] +打印([t])< /代码>,在我删除了中间的括号(<代码>打印(t)< /代码>)之后,按照您的建议,它运行良好。“
[[]]
可以写成[[[].[]]]
”刚刚为我解开了这里的所有谜团。很有说明性的回答!