Erlang判断记录是不是有字段

Posted

技术标签:

【中文标题】Erlang判断记录是不是有字段【英文标题】:Erlang determine if record has a fieldErlang判断记录是否有字段 【发布时间】:2014-06-17 09:28:34 【问题描述】:

我正在更新我保存在 mnesia 中的记录模式。新架构包含一个新字段,我想在通过 id 读取记录后检查记录是否具有该字段,如果没有,则将记录更新为新架构。

所以,例如我们的旧记录是这样的:

-record(cust, id, name, street_address, city, state, zip)。

新记录添加字段 street_address2:

-record(cust, id, name, street_address, street_address2, city, state, zip)。

我希望能够即时升级现有记录的架构。要使用当前逻辑执行此操作,我需要按 id 查找记录,检查记录是否存在 address_line2 字段。如果不存在,将其设置为原子 undefined 并保存回 mnesia。出于某种原因,我很难找到一个好的方法来做到这一点。

任何指导将不胜感激。

【问题讨论】:

【参考方案1】:

根据 Ulf Wiger 在https://groups.google.com/forum/#!topic/erlang-programming/U6Q0-_Usb50 的回复,您确实需要使用mnesia:transform_table(Tab, Fun, NewAttributeList) 调用来转换表格。

http://erldocs.com/R16B03-1/mnesia/mnesia.html?i=1&search=mnesia#mnesia

此函数将参数 Fun 应用于表中的所有记录。 fun 是一个函数,它获取旧类型的记录并返回新类型的转换记录。

【讨论】:

【参考方案2】:

亚历克斯是正确的。这是一个使用 transform_table 进行描述的示例:

-record(cust, id, name, street_address, street_address2, city, state, zip). % This should be the record definition

mnesia:transform_table(
 cust, 
 fun(cust,
           Id,
           Name,
           StreetAddress,
           City,
           State,
           Zip
      ) ->
      cust,
           Id,
           Name,
           StreetAddress,
           undefined, % This is setting it to the atom undefined.  You could also do "", or anything you want.
           City,
           State,
           Zip
      
 end,
 record_info(fields, cust)
).

发生的情况是第一个元组中的变量(Id、Name、StreetAddress 等)从现有记录中自动设置。然后将记录转换为第二个元组(有趣的返回),使用这些设置变量来分配新值。此过程适用于表中的每条现有记录。

请记住,该功能在任何方面都不是神奇的,因此您可以在其中做任何您需要做的事情,例如检查 id 或其他任何事情。但是对于简单地向记录添加一个字段,您可以像我在这里展示的那样做。

如果您是从控制台执行此操作,请务必使用 rr() 或其他方式加载记录定义。

这里是 transform_table 的文档:http://www.erlang.org/doc/man/mnesia.html#transform_table-3

【讨论】:

非常感谢@Adam 和@Alexander!我将这个标记为答案,因为它更彻底,并回答了我在 erl 文档中无法确定的几个问题。

以上是关于Erlang判断记录是不是有字段的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Erlang 中的模式匹配记录会抛出错误

不是语言之争--Go vs Erlang

Erlang和运行时记录限制

在列表中查找字段的位置 Erlang

列出 Erlang 中进程可用的可用记录

如何在 Erlang 中的多个 erl 之间共享记录?