2015-06-18 18 views

risposta

78

È necessario utilizzare la funzione struct/2. Dalla documentazione:

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"} 
+2

Se si è imposto chiavi e vuole fare in modo che esistono nell'uso mappa 'struct!/2' invece. – RusinaRange

+1

Sono confuso. Questa risposta mostra l'inizializzazione di una struttura da un elenco di parole chiave. Ma la domanda si interroga su struct da una mappa. –

+1

Trovato! 'struct/2' funziona anche per una mappa. Quindi, 'opts =% {name:" meg "}' funziona. –

22

Le risposte precedenti sono entrambi buoni, con uno avvertenza: le chiavi nella struttura sono atomi, le chiavi nel tuo hash potrebbero essere stringhe. L'utilizzo del metodo struct() copia solo le chiavi corrispondenti, e le stringhe non corrispondono agli atomi. Esempio:

defmodule User do 
    defstruct name: "john" 
end 

opts = %{"name" => "meg"} 
user = struct(User, opts) 
#=> %User{name: "john"} 

Utilizzando merge è strano, troppo, perché sarà "annullare" la natura struct della Mappa:

user = Map.merge(%User{}, opts) 
#=> %{:__struct__ => User, :name => "john", "name" => "meg"} 

trovato questo sul elisir-lang-talk Google Group, da Jose stesso:

https://groups.google.com/d/msg/elixir-lang-talk/6geXOLUeIpI/L9einu4EEAAJ

che è praticamente la strada da percorrere ad eccezione si può fare tutto in un solo passaggio:

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 
+1

La risposta di Jose (e la tua per detrazione) dovrebbe essere accettata, per la ragione di essere di Jose (scherzando). Usare l'unione mi ha causato problemi, e sì, hai completamente perso la natura della struttura. – sixFingers

+0

Grazie per questo, avevo bisogno di un modo abbastanza generico per inizializzare le strutture da tutti i tipi di mappe e questa era la base del mio trucco per fare questo https://github.com/chrisjowen/ExMapper – Owen

Problemi correlati