下面的操作是否可以在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.
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,你会发现堆栈在增加。因此,编译器会判断出这是一个尾部调用,并对其进行优化,即使它不是递归尾部调用。
lf5gs5x22#
我的直觉是否定的,因为所写的函数不是尾递归的。
2条答案
按热度按时间zbsbpyhn1#
很容易尝试看看会发生什么:
如果你运行loop:loop(),你会发现它实际上并没有增加堆栈。如果你在调用drop(ok)或loop()之后添加一个,1,你会发现堆栈在增加。
因此,编译器会判断出这是一个尾部调用,并对其进行优化,即使它不是递归尾部调用。
lf5gs5x22#
我的直觉是否定的,因为所写的函数不是尾递归的。