可以在erlang中完成以下操作,并且不会因内存堆问题而导致崩溃吗?
loop() ->
receive
{drop, X} -> drop(X);
X -> handle(X)
end.
handle(X) ->
case X of
ok -> loop()
end.
drop(X) ->
case X of
ok -> loop()
end.
答案 0 :(得分:6)
尝试看看会发生什么很容易:
-module(loop).
-compile(export_all).
loop() ->
receive
{drop, X} -> drop(X);
after 1000 ->
erlang:display(catch erlang:error(noes)),
drop(ok)
end.
drop(X) ->
case X of
ok -> loop()
end.
如果你运行loop:loop(),你会发现它确实没有增加堆栈。如果在调用drop(ok)或loop()之后添加1,则会看到堆栈增长。
所以编译器发现它是一个尾调用并优化它,即使它不是一个递归的尾调用。
答案 1 :(得分:1)
我的直觉猜测是否定的,因为所写的函数不是尾递归的。