でも、あなたの編集はない末尾再帰的である:1つの関数の実行順序がある
loop() ->
receive
{sys, Msg} ->
handle_sys_msg(Msg),
loop();
{From, Msg} ->
Reply = handle_msg(Msg),
From ! Reply,
loop();
_ -> continue
end,
loop().
:receive ... end, loop()
。あなたが{sys, _}
メッセージを得れば今、loop/0
は、上記と同等のものに実行順序を変換し、内部から受け取ると呼び出されます。
loop() ->
receive
loop() ->
receive
...
end,
loop(),
end,
loop() ->
...
問題は、内からloop()
を呼び出す場合、受け取るということですreceive
の後にloop()
を実行するには、VMは引き続きリターンポイントを格納する必要があります。
あなたの関数は末尾再帰にするために、あなたがいずれかを実行する必要があります:
loop() ->
receive
{sys, Msg} ->
handle_sys_msg(Msg);
{From, Msg} ->
Reply = handle_msg(Msg),
From ! Reply;
_ -> continue
end,
loop().
または
loop() ->
receive
{sys, Msg} ->
handle_sys_msg(Msg),
loop();
{From, Msg} ->
Reply = handle_msg(Msg),
From ! Reply,
loop();
_ -> loop()
end.
loop()
を呼び出すと、実際に行われる常に最後の事です関数。
あなたの編集は末尾再帰です。つまり、スタック上に何も構築されません。 – Lukas
@TERRIBLE ADVICEはあなたの編集が尾部再帰的ではないことを非常に正しく指摘しています – rvirding