2014-11-04 114 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> 
相關問題