2015-06-26 62 views
4

以下代碼是由Manning發佈的'Elixir in Action'複製粘貼的。實例化新結構時使用`|'

defmodule TodoList do 

    defstruct auto_id: 1, entries: HashDict.new 

    def new, do: %TodoList{} 

    def add(
    %TodoList{entries: entries, auto_id: auto_id} = todo_list, 
    entry) do 
     entry = Map.put(entry, :id, auto_id) 
     new_entries = HashDict.put(entries, auto_id, entry) 
     %TodoList{ todo_list | 
     entries: new_entries, 
     auto_id: auto_id + 1 
     } 
    end 

end 

創建新TodoList時,我不明白在add函數的末尾使用todo_list |。我試圖徹底刪除它,結果無法看到差異。任何人都可以向我解釋它實現了什麼?

回答

8

這是用於更新地圖語法速記:

iex> map = %{foo: "bar"} 
%{foo: "bar"} 

iex> map = %{map | foo: "quux"} 
%{foo: "quux"} 

注意,不像Map.put/3,你只能更新現有的密鑰,它爲您提供了一些安全性。它的行爲更像Erlang的:maps.update/3

iex> map = %{map | baz: "quux"} 
** (ArgumentError) argument error 
    (stdlib) :maps.update(:baz, "quux", %{foo: "bar"}) 
    (stdlib) erl_eval.erl:255: anonymous fn/2 in :erl_eval.expr/5 
    (stdlib) lists.erl:1261: :lists.foldl/3 

還要注意的是像你%TodoList{}結構其實只是地圖,所以這一切的工作原理完全相同的方式與結構。

現在,因爲您正在設置結構的所有有效密鑰,所以您現在是否將todo_list |放在那裏或沒有。但是,如果將新密鑰添加到結構中,您的add函數可能無法按預期方式工作,丟棄其他密鑰。所以我建議你把它放在那裏。