Erlang接收和正确的调用结构

z0qdvdin  于 2022-12-08  发布在  Erlang
关注(0)|答案(2)|浏览(143)

下面的操作是否可以在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.
zbsbpyhn

zbsbpyhn1#

很容易尝试看看会发生什么:

-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,你会发现堆栈在增加。
因此,编译器会判断出这是一个尾部调用,并对其进行优化,即使它不是递归尾部调用。

lf5gs5x2

lf5gs5x22#

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

相关问题