2017-05-09 125 views
1

說我有一個函數,稍微冗長,每次調用相同的參數,這個函數也需要很多做一些設置之前,可以調用該模塊的任何其他功能它的回調。Elixir - 通過函數參數

SomeMod.called_a_lot(‘xx’, fn(y) -> 
    SomeMod.needs_called_a_lot_to_be_called_first(‘do_stuff’) 
end) 

我想,我可以把它包像這樣:

defp easier_to_call(func) do 
    SomeMod.called_a_lot(‘xx’, fn(y) -> func(y) end 
end 

然後用它像這樣:

easier_to_call(fn(y) -> 
    SomeMod.needs_called_a_lot_to_be_called_first(‘do_stuff’) 
end) 

怎樣才能實際上做到這一點的靈藥?

+1

你的代碼看起來不錯;只要將'func(y)'改爲'func。(y)',因爲它是一個匿名函數。 – Dogbert

回答

1

你的語法,只是有點過調用匿名函數。您將需要使用的

func.(y) 

代替

func(y) 

,因爲它是一個匿名函數。

查看Elixir Crash Course的簡單例子。

1

Dogbert的評論是正確的。但既然你不修改參數,你可以只通過功能上沒有一個匿名函數進行包裝:

defp easier_to_call(func) do 
    SomeMod.called_a_lot(‘xx’, func) 
end 
1

我真的不明白你到底在問什麼,但我覺得你正在尋找capture operator (&)

一個例子使用將是:

easier_func = &SomeMod.called_a_lot(‘xx’, &1) 

easier_func.(fn(_y) -> 
    SomeMod.needs_called_a_lot_to_be_called_first(‘do_stuff’) 
end) 

隨着&1是在匿名函數的第一個參數。

如果你需要一個多參數數量匿名函數,那麼你可以這樣做:

easy_reduce = &Enum.reduce(&1, 0, &2) 

easy_reduce.([1,2,3,4], fn(x, acc) -> acc + x end) # => 10 
1

只是爲了展示另一種方法:它可能會與宏來實現,調用該函數被調用,然後再調用塊:

defmodule Test do 
    defmacro with_prepended(arg, do: block) do 
    quote do 
     IO.inspect(unquote(arg), label: "In function") 
     prepended(unquote(arg)) 
     unquote(block) 
    end 
    end 
end 

defmodule Tester do 
    require Test 

    defp prepended(arg), do: IO.inspect(arg, label: "In prepended") 

    def fun(arg) do 
    Test.with_prepended(arg) do 
     IO.puts "Actual code" 
    end 
    end 
end 

Tester.fun(42) 

#⇒ In function: 42 
#⇒ In prepended: 42 
#⇒ Actual code