在Elixir中,你如何用一个mapvariables初始化一个结构体
我知道它有可能通过%User{ email: 'blah@blah.com' }
创build一个结构体。 但是,如果我有一个variablesparams = %{email: 'blah@blah.com'}
是否有一种方法来创build该结构使用该variables例如%User{ params }
。
这给出了一个错误,只是想知道你是否可以爆炸或以其他方式?
你应该使用struct/2
函数。 从文档:
defmodule User do defstruct name: "john" end struct(User) #=> %User{name: "john"} opts = [name: "meg"] user = struct(User, opts) #=> %User{name: "meg"} struct(user, unknown: "value") #=> %User{name: "meg"}
以前的答案都是好的,一个警告:结构中的键是primefaces,你的散列键可能是string。 使用struct()方法将只复制匹配的键,string将不匹配primefaces。 例:
defmodule User do defstruct name: "john" end opts = %{"name" => "meg"} user = struct(User, opts) #=> %User{name: "john"}
使用合并也很奇怪,因为它会“撤消”Map的结构性质:
user = Map.merge(%User{}, opts) #=> %{:__struct__ => User, :name => "john", "name" => "meg"}
从何塞本人那里得到了这个关于elixir-lang-talk的Google小组:
https://groups.google.com/d/msg/elixir-lang-talk/6geXOLUeIpI/L9einu4EEAAJ
这是相当多的路要走,除了你可以一口气做一切:
def to_struct(kind, attrs) do struct = struct(kind) Enum.reduce Map.to_list(struct), struct, fn {k, _}, acc -> case Map.fetch(attrs, Atom.to_string(k)) do {:ok, v} -> %{acc | k => v} :error -> acc end end end
另一种使用Map.merge/2
:
合并(map1,map2)
例:
params #=> %{email: "blah@blah.com"} %User{} |> Map.merge(params) #=> %User{ email: 'blah@blah.com' }