2017-05-30 42 views
0

有人可以解釋爲什麼在Elixir中需要「捕獲操作符」,表示爲&符號前綴?在其他語言中是不是:爲什麼我們需要在Elixir中使用「捕獲操作符」函數?

Python 3.6.0 |Anaconda 4.3.0 (64-bit)| (default, Dec 23 2016, 12:22:00) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux 

>>> def double(x): 
... return(x + x) 
... 
>>> double(2) 
4 
>>> dbl = double 
>>> dbl(2) 
4 

這個作品在仙丹一樣,顯然是:

iex(2)> double = fn x -> x + x end 
#Function<6.118419387/1 in :erl_eval.expr/5> 
iex(3)> double.(2) 
4                                 
iex(4)> dbl = double                            
#Function<6.118419387/1 in :erl_eval.expr/5>                      
iex(5)> dbl.(2)                             
4  

那麼,爲什麼,例如here,做我們永遠需要的,如果該函數使用捕獲操作已經可以在沒有運營商的情況下通過?函數的普通舊名稱是否已經「捕獲」它?

iex(10)> Enum.map([1, 2, 3], double) 
[2, 4, 6] 

基本上我不明白的&捕獲操作和優勢是什麼它提供的使用情況。

+1

也許它是這樣的,你可以通過'/ 1''/2'等後綴表示法來包含參數的數量,否則它會被解釋爲一個分割。在函數式語言中,當參數的數量和類型改變時,函數可以是完全不同的聲明。 – GavinBrelstaff

回答

3

在上例中,您將匿名函數fn x -> x + x end綁定到變量double。捕獲操作符在您傳遞一個命名函數時使用。保存/傳遞一個命名的函數,你需要一種方式來表示它的一個命名函數,而不是一個變量。這是您使用捕獲&名稱/ arity語法的地方。

defmodule FunWithFuns do 
    def get_env, do: Application.get_all_env(:my_app) 
    def get_env(item), do: Application.get_env(:my_app, item) 

    def some_function do 
    IO.inspect get_env 
    Enum.map([:item1, :item2], get_env) 
    end 
end 

你如何解決在這種情況下get_env。它是對get_env/0的調用,還是對get_env/1的引用?在匿名函數的情況下,double是變量綁定,double.(1)是綁定到變量double的函數的調用。

請注意,不帶()的調用零值函數已被棄用,但仍然有效。我想,一旦被刪除,編譯器可能會作出選擇,但即使如此,可能還有其他原因,爲什麼它仍然無法正常工作。

另一個原因。例如,假設我們使用指定的函數名稱進行了支持。我們怎麼能支持這一點:

# contrived example 
defmodule MoreFunWithFuns do 
    def fun1, do: :something_stateful 
    def fun1(x), do: x + 1 

    def higher(list, fun) do 
    cond do 
     is_function(fun, 0) -> fun.() |> process_state 
     is_function(fun, 1) -> Enum.map(list, fun) |> process_state 
    end 
    end 

    def run(list) do 
    higher(list, fun1) # which fun1 here? 
    end 
end 

變量只能有一個在時間結合。所以,關於它的引用是沒有歧義的。然而,一個命名的函數可能有多個原因與不同的arities。所以,如果我們只提供函數名稱,那麼我們所指的是哪一個子句也不明確。

相關問題