Elixir如何将Map结构转换为Record结构

时间:2015-03-06 03:08:40

标签: elixir

我有一个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

但是如何将地图转换为记录?

2 个答案:

答案 0 :(得分:13)

Elixir Records are deprecated。现在存在于Elixir中的Record模块仅用于两件事:

  1. 使用简短的内部数据
  2. 与Erlang记录接口
  3. 这意味着除非您尝试从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