Die vorherigen Antworten sind beide gut, mit einer Einschränkung: Die Schlüssel in der Struktur sind Atome, die Schlüssel in Ihrem Hash können Zeichenfolgen sein. Bei Verwendung der struct () -Methode werden nur die übereinstimmenden Schlüssel kopiert, und Zeichenfolgen stimmen nicht mit den Atomen überein. Beispiel:
defmodule User do
defstruct name: "john"
end
opts = %{"name" => "meg"}
user = struct(User, opts)
#=> %User{name: "john"}
Die Verwendung von Merge ist ebenfalls seltsam, da dadurch die Struktur der Map "rückgängig gemacht" wird:
user = Map.merge(%User{}, opts)
#=> %{:__struct__ => User, :name => "john", "name" => "meg"}
Fand dies in der elixir-lang-talk Google Group von Jose selbst:
https://groups.google.com/d/msg/elixir-lang-talk/6geXOLUeIpI/L9einu4EEAAJ
Das ist so ziemlich der richtige Weg, außer dass Sie alles in einem Durchgang erledigen können:
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
struct!/2
stattdessen.