使用Erlang,我有一个进程循环函数,如:
process_loop(...A long list of parameters here...) ->
receive
...Message processing logic involving the function parameters...
end,
process_loop(...Same long list of parameters...)
end.
看起来很难看,所以我尝试了这样的重构:
process_loop(...A long list of parameters...) ->
Loop = fun() ->
receive
...Message processing logic...
end,
Loop()
end,
Loop()
end.
但事实证明这是不正确的,因为Loop变量在Loop函数中未绑定。所以,我已经安排了一个解决方法:
process_loop(...A long list of parameters...) ->
Loop = fun(Next) ->
receive
...Message processing logic...
end,
Next(Next)
end,
Loop(Loop)
end.
我有两个问题:
有没有办法实现代码片段#2的想法,但没有这样的“下一步(下一步)”解决方法?
片段#1和#3在性能方面有显着差异,还是相同?
答案 0 :(得分:2)
您可以使用元组/记录作为命名参数,而不是传递大量参数。您可以重用函数将要使用的单个参数。
我猜(但我不确定)正确的尾递归不支持这种语法。如果您重构使用单个参数,我认为您将再次走上正轨。
答案 1 :(得分:2)
没有。不幸的是匿名功能就是这样。匿名,除非你给他们起个名字。
Snippet#3有点贵。鉴于你对正文中的消息进行模式匹配,我不担心。在这种情况下,优化可读性。差异是一个非常小的常数因素。
答案 2 :(得分:0)
避免在代码段#1中重复参数列表的更常规方法是将所有或大部分参数放在保存循环状态的记录中。然后你只有一个或几个变量在循环中传递。这比阅读递归的乐趣更容易阅读和更难搞乱。
答案 3 :(得分:0)
我必须说,在我进行这种类型的递归的所有情况下,我都不认为我曾经遇到过在递归中传递相同变量集的情况。通常,变量将改变反映过程循环中的状态变化。它不可能是你必须明确处理状态。我通常将相关参数分组到记录中,这减少了参数的数量并增加了清晰度。
你当然可以使用你的解决方案,并在有趣的情况下隐藏一些参数,在递归调用中有一些显式但我不认为这会提高清晰度。
同样的答案适用于你正在踩过数据结构的“正常”递归。