Nice programing

Elixir에서 맵 변수로 구조체를 어떻게 초기화합니까?

nicepro 2020. 11. 10. 22:17
반응형

Elixir에서 맵 변수로 구조체를 어떻게 초기화합니까?


을 통해 구조체를 만들 수 있다는 것을 알고 있습니다 %User{ email: 'blah@blah.com' }. 그러나 변수 params = %{email: 'blah@blah.com'}가 있으면 해당 변수를 사용하여 해당 구조체를 만드는 방법이 있습니다 %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"}

이전 답변은 모두 좋습니다. 한 가지주의 사항이 있습니다. 구조체의 키는 원자이고 해시의 키는 문자열 일 수 있습니다. struct () 메서드를 사용하면 일치하는 키만 복사되며 문자열은 원자와 일치하지 않습니다. 예:

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

Jose가 직접 만든 elixir-lang-talk Google Group에서 다음을 발견했습니다.

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' }

참고 URL : https://stackoverflow.com/questions/30927635/in-elixir-how-do-you-initialize-a-struct-with-a-map-variable

반응형