2014-11-04 86 views
2

Erlang非常重视可读性。将匿名函数作为参数传递给Erlang中的函数?

模式匹配,列表解析是很好的工具,可以最大限度地减少代码,而不会实际上破坏可读性。 但是,通常匿名函数作为erlang中的函数参数传入。

对我来说,这是讨厌的阅读that.Is有什么特别的原因,为什么这样做?

exmple一般:

hhfuns:fold(fun(A,B) -> A + B end, 0, lists:seq(1,6)). 
+0

请提供一个例子。 – bereal 2014-11-04 05:53:53

+0

@bereal:ok..2分钟 – 2014-11-04 05:55:04

回答

3

您可以处理此你喜欢的任何方式。起初语法可能很烦人,但你可能会习惯它。在任何情况下,您都尝试将传递给函数,这与您做其他任何参数的方式相同。如果你牢记这一点,你会意识到你有三种方式来做到这一点。

请看下面的例子模块:

-module(funplay). 
-export([external/1, internal/1, inline/1]). 

apply_foo(Foo, Thingy) -> Foo(Thingy). 

add_one(N) -> N + 1. 

external(X) -> 
    apply_foo(fun add_one/1, X). 

internal(X) -> 
    AddOne = fun(N) -> N + 1 end, 
    apply_foo(AddOne, X). 

inline(X) -> 
    apply_foo(fun(N) -> N + 1 end, X). 

我想不出什么更好的方式来解释它比上面的代码。

如果我知道我会在一堆地方使用相同的东西(在这种情况下,我确实需要定义过程,而不是在任何地方匿名重写),我更喜欢外部方式。每当我需要将一个不平凡的或多行的条件传递给一个函数时(我更容易阅读,而且我讨厌参数中的缩进),或者如果我在同一个函数中多次需要它,我更喜欢内部方式,我更喜欢内联的方式来进行琐碎的检查,比如过滤器或折叠。

+0

不能外部像 外部(X) - > add_one(x)。 – 2014-11-04 06:44:00

+2

@DarkHorse当然可以!但是这打破了展示以功能作为论据的三种方式的目的,所以我没有这样做。 :-)当你进入更有趣的例子时,比如'external/1'有其他工作要做,而不是简单地将另一个函数应用到它的参数中(例如记录动作发生的情况),那么你必须做这件事办法。 – zxq9 2014-11-04 06:45:32

+0

Genius.Thx.so我们可以直接传递参数并在内部函数调用中使用它。我将坚持它和外部函数。 – 2014-11-04 06:48:27

1

选择语法是一个品味或公司编码规则的问题,但有趣的是这个功能的强大。这里是一个例子,我将消息中的函数发送给另一个节点,然后依次转发到最终执行它的进程列表(请注意,我选择匿名函数,这样做我确信接收节点将能够执行该功能):

开始2个节点:在壳

erl -sname node1 
erl -sname node2 

在node1,(需要R17与此语法工作):

Loop = fun Loop(X) -> receive            
{forward, Mess} -> lists:foreach(fun(Pid) -> Pid ! Mess end, X), Loop(X); 
stop -> ok                 
end                  
end. 

Proc = fun Proc(X) -> receive 
{do,Fun} -> Y = Fun(X), Proc(Y); 
stop -> ok      
end        
end.       

L = [spawn(fun() -> Proc(0) end) || _ <- lists:seq(1,10)]. 

register(server,spawn(fun() -> Loop(L) end)). 

在node2:

([email protected])1>net_adm:ping([email protected]).                
pong    
([email protected])2> {server,[email protected]} ! {forward,{do,fun(X) ->Self = self(), io:format("~p state is ~p~n",[Self,X]),X end}}. 
{forward,{do,#Fun<erl_eval.6.90072148>}} 
([email protected])3> {server,[email protected]} ! {forward,{do,fun(X) -> X + 1 end}}.        
{forward,{do,#Fun<erl_eval.6.90072148>}} 
([email protected])4> {server,[email protected]} ! {forward,{do,fun(X) ->Self = self(), io:format("~p state is ~p~n",[Self,X]),X end}}. 
{forward,{do,#Fun<erl_eval.6.90072148>}} 
([email protected])4> 

在node1结果:

<0.42.0> state is 0 
<0.43.0> state is 0 
<0.44.0> state is 0 
<0.45.0> state is 0 
<0.46.0> state is 0 
<0.47.0> state is 0 
<0.48.0> state is 0 
<0.49.0> state is 0 
<0.50.0> state is 0 
<0.51.0> state is 0 
<0.43.0> state is 1 
<0.42.0> state is 1 
<0.44.0> state is 1 
<0.45.0> state is 1 
<0.46.0> state is 1 
<0.47.0> state is 1 
<0.48.0> state is 1 
<0.49.0> state is 1 
<0.50.0> state is 1 
<0.51.0> state is 1 
([email protected])5> 
相关问题