以下代码是从' 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
我不了解在创建新todo_list |
时在add
函数末尾使用TodoList
。我尝试完全删除它,但结果并没有真正看出差异。任何人都可以向我解释它的成就吗?
答案 0 :(得分: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
函数可能无法正常工作,丢弃其他密钥。所以我建议你把它放在那里。