Erlang内部函数的递归
在使用 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的想法,但没有这样的“Next(Next)”解决方法?
代码段 #1 和 #3 在性能方面是否存在显着差异,或者它们是等效的?
Playing with Erlang, I've got a process-looping function like:
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.
It looks quite ugly, so I tried a refactoring like that:
process_loop(...A long list of parameters...) ->
Loop = fun() ->
receive
...Message processing logic...
end,
Loop()
end,
Loop()
end.
But it turned out to be incorrect, as Loop variable is unbound inside the Loop function. So, I've arranged a workaround:
process_loop(...A long list of parameters...) ->
Loop = fun(Next) ->
receive
...Message processing logic...
end,
Next(Next)
end,
Loop(Loop)
end.
I have two questions:
Is there a way to achieve the idea of snippet #2, but without such "Next(Next)" workarounds?
Do snippets #1 and #3 differ significantly in terms of performance, or they're equivalent?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
没有。不幸的是,匿名函数就是这样。匿名,除非你给它们一个名字。
代码段#3 有点贵。鉴于您对正文中的消息进行模式匹配,我不会担心这一点。在这种情况下优化可读性。差异是一个非常小的常数因子。
No. Unfortunately anonymous function are just that. Anonymous, unless you give them a name.
Snippet #3 is a little bit more expensive. Given that you do pattern matching on messages in the body, I wouldn't worry about it. Optimise for readability in this case. The difference is a very small constant factor.
您可以使用元组/记录作为命名参数,而不是传递大量参数。您可以只重用该函数将采用的单个参数。
我猜(但我不确定)正确的尾递归不支持此语法。如果您重构为使用单个参数,我认为您将再次走上正确的轨道。
You might use tuples/records as named parameters instead of passing lots of parameters. You can just reuse the single parameter that the function is going to take.
I guess (but I' not sure) that this syntax isn't supported by proper tail-recursion. If you refactor to use a single parameter I think that you will be again on the right track.
避免重复代码片段 #1 中的参数列表的更传统方法是将所有或大部分参数放入保存循环状态的记录中。那么你就只有一个或几个变量可以在循环中传递。与玩弄递归的乐趣相比,这更容易阅读,也更难搞砸。
The more conventional way of avoiding repeating the list of parameters in snippet #1 is to put all or most of them in a record that holds the loop state. Then you only have one or a few variables to pass around in the loop. That's easier to read and harder to screw up than playing around with recursive funs.
我必须说,在我执行此类递归的所有情况下,我认为我从未遇到过在递归中传递完全相同的相同变量集的情况。通常变量会发生变化,反映过程循环中的状态变化。不可能是其他情况,因为您必须显式处理状态。我通常将相关参数分组到记录中,这样可以减少参数数量并增加清晰度。
您当然可以使用您的解决方案,并在乐趣中隐含一些参数,在递归调用中使用一些显式参数,但我认为这不会提高清晰度。
同样的答案适用于“正常”递归,其中您正在逐步跳过数据结构。
I must say that in all cases where I do this type of recursion I don't think I have ever come across the case where exactly the same set of variables is passed around in the recursion. Usually variables will change reflecting state change in the process loop. It cannot be otherwise as you have to handle state explicitly. I usually group related parameters into records which cuts down the number of arguments and adds clarity.
You can of course use your solution and have some parameters implicit in the fun and some explicit in the recursive calls but I don't think this would improve clarity.
The same answer applies to "normal" recursion where you are stepping over data structures.