Erlang接收和正确的呼叫结构

时间:2012-01-19 20:32:21

标签: memory erlang heap

可以在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.

2 个答案:

答案 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)

我的直觉猜测是否定的,因为所写的函数不是尾递归的。