我有一个Record结构和一个Map结构,如:
defmodule Foo.Bar do
defstruct boo: nil, baz: nil
end
defmodule Foo do
require Record
Record.defrecord :bar, Foo.Bar, [boo: nil, baz: nil]
end
我可以像这样将记录转换为地图:
defp update_map({k, v}, map), do: Map.update!(map, k, fn(_) -> v end)
defp rd2map(rd) do
Foo.bar(rd) |> Enum.reduce(%Foo.Bar{}, &update_map/2)
end
但是如何将地图转换为记录?
答案 0 :(得分:13)
Elixir Records are deprecated。现在存在于Elixir中的Record
模块仅用于两件事:
这意味着除非您尝试从Erlang文件中提取记录信息,否则您可能不应该使用它们。
关于你原来的问题,这里是我如何来回转换Erlang Records和Elixir Structs。一旦你意识到一个结构只是一个包含Map
的{{1}},而一个记录只是一个以__struct__: Foo.Bar
开头的元组,它非常简单。唯一棘手的一点是有关记录字段的信息仅在编译时可用。因此,默认情况下没有动态构建记录的方法。据我所知,你只能通过在某处存储字段定义来解决这个问题,并使用它来生成结构和记录定义。稍后,重新使用相同的源来构建具有默认值(即记录)的有序元组。请记住,真的不应该使用记录。因此,请注意:前方丑陋的黑客; - )
{Foo.Bar, ...}
答案 1 :(得分:2)
帕特里克的所有免责声明和信息都是正确的。如果不注释字段,就无法在运行时解决问题。
但是,如果要从Erlang记录转换(这主要是使用它们的唯一原因),则可以在编译时解决此问题。我们在Elixir源代码上执行此操作,将Erlang的#file_info{}
转换为%File.Stat{}
:
https://github.com/elixir-lang/elixir/blob/master/lib/elixir/lib/file/stat.ex