2017-05-09 121 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