不,您使用Acc
不会使其尾递归。如果您的分支返回[H| remove(T, Key, Acc)]
这不是尾巴呼叫,并且此分支将在大部分时间使用。更确切地说,您使用Acc
是无用的,因为它将是整个时间的[]
,您根本不会改变它的值。正确的代码应该看起来像。
delete(Key, Database) ->
remove(Database, Key, []).
remove([], Key, Acc) ->
lists:reverse(Acc);
remove([H|T], Key, Acc) ->
if
element(1, H) /= Key ->
remove(T, Key, [H|Acc]);
true ->
remove(T, Key, Acc)
end.
但如果你的列表成员总是对我宁愿直接模式匹配:
delete(Key, Database) ->
remove(Database, Key, []).
remove([], Key, Acc) ->
lists:reverse(Acc);
remove([{Key, _}|T], Key, Acc) ->
remove(T, Key, Acc);
% if it should delete only first occurrence then lists:reverse(Acc, T);
remove([H|T], Key, Acc) ->
remove(T, Key, [H|Acc]).
但我认为这是例子可以申请Myth: Tail-recursive functions are MUCH faster than recursive functions所以我会用更简单的递归版本:
delete(Key, []) -> [];
delete(Key, [{Key, _}|T]) -> delete(Key, T);
% if it should delete only first occurrence then just T;
delete(Key, [H|T]) -> [H | delete(Key, T)].
如果你想知道是否是尾递归,是否有什么需要返回函数返回前的调用值。在这种情况下,cons正在等待结果,所以不,它不是尾递归。 – Dustin 2010-04-17 22:14:31
这是我在这里回答你的问题的一个的改写:http://stackoverflow.com/questions/2658631/tail-recursion-in-erlang/2658766#2658766 – 2010-04-18 06:15:03
@Jeremy这是不是一个完整的改写,因为我期待有关if语句指导,但我拿点,不会再发布关于这一主题。 – dagda1 2010-04-18 10:03:57