尾递归就是在一系列语句的最后又跳转到被调用函数的开头。这里的“最后”两个字很关键,不正确的递归调用会吃光你的内存。
litaocheng 在他的blog中就提到过一个很好的例子:here
观察下面的代码:
do_t1() ->
try
recive
_->
do_t1()
end
catch
_:_ ->
do_t1()
end.
这段代码之所以不是尾递归是因为:在未抛出异常的情况下,函数中最后一个语句是try....catch 而不是 do_t1/0
如果非要把以上代码改成尾递归,那么该怎么改呢?
以下两段代码哪个正确?
do_t1() ->
receive
_ ->
try
do_t1()
catch
_:_ ->
do_t1()
end
end.
do_t1() ->
receive
_ ->
try
.......
catch
_:_ ->
do_t1()
end,
do_t1()
end.
如果要对原文中的以下代码进行改造(这里不考虑gen_server),那么应该如何修改?
send_msg(Socket, Pid) ->
try
receive
{send, Bin} ->
...
{inet_reply, _Sock, Result} ->
...
catch
_:_ ->
send_msg(Sock, Pid)
end.
参考以下代码:
send_msg(Socket, Pid) ->
Result=
try
receive
{send, Bin} ->
...
{inet_reply, _Sock, Result} ->
...
catch
_:_ ->
{error,"exception"}
end,
case Result of
{error,_Er}->
send_msg(Sock, Pid);
Else->
Else
end
.