通过编程方式指定要修改的字段来修改Erlang中的记录

通过编程方式指定要修改的字段来修改Erlang中的记录,erlang,record,Erlang,Record,当对我们以编程方式指定的字段进行修改时,有没有相对简单的方法(复制和)修改Erlang中的记录 例如: -record(my_record, {foo = 0, bar = 0}). modify_record(Record, Field, Value) -> Record#my_record{Field = Value}. 这样我们就可以做类似于modify\u record(#my\u record{foo=1},bar,42),或者modify\u record(一些返回我的

当对我们以编程方式指定的字段进行修改时,有没有相对简单的方法(复制和)修改Erlang中的记录

例如:

-record(my_record, {foo = 0, bar = 0}).

modify_record(Record, Field, Value) ->
  Record#my_record{Field = Value}.
这样我们就可以做类似于
modify\u record(#my\u record{foo=1},bar,42)
,或者
modify\u record(一些返回我的记录()的方法,foo,3.14)

编译类似的东西时会出现如下错误

field 'Field' is not an atom or _ in record my_record

我意识到有一些关于如何转换为/从proplist的例子,但我希望有更简单的东西。

您可以使用类似于

在您的模块中,您必须通过在顶部包含以下内容来指定解析转换:

-compile({parse_transform, dynarec}).
此解析转换将在编译时修改模块,方法是为该模块中定义或包含的所有记录插入setter和getter

这意味着你可以做一些类似的事情:

NewRecord = set_value(field_name, Value, Record)
我建议阅读dynarec顶部的注释,因为它包含了更完整的示例


我希望这会有所帮助。

您可以让它像这样工作:

modify_record(Record, Field, Value) ->
 case Field of 
   foo -> Record#my_record{foo = Value},
   bar -> Record#my_record{bar = Value}
 end.

记录是纯编译时的,因此所有内容都必须在编译时知道。这意味着您无法在运行时计算字段名,这是您想要做的。@ligaoren和@chops给出的方法是处理这个问题的两种方法,但是,正如您所看到的,这两种方法都在编译时完成它们的工作。

如果您传递字段号(而不是字段名),那么这是可能的。意思是你调用函数

modify_record(MyRecord, #my_record.foo, 3.14)
而不是

modify_record(MyRecord, foo, 3.14)
(#my_record.foo返回记录中foo字段的编号)。在这种情况下,您的修改记录可能是

  modify_record(R, FieldNo, Val) -> setelement(FieldNo,R,Val).

我以前也研究过这个问题。但记录只是存在于编译时的元组。我希望有一些元编程技巧可以做到这一点。是的,这让我相信它应该是可行的,因为从原子到场的映射是在中编译的。对于无效字段,它必须发出某种错误信号,但这是意料之中的。不,这是不可行的。关于记录的所有内容都是在编译时计算出来的。你到底想做什么?您希望如何使用它。我正在构建验证测试,从有效记录开始,修改各个字段以测试验证代码。但这不重要吗?从字段名的原子到字段在记录中的位置的映射在运行时是已知的,因此使用@Odobenus建议的方法似乎是可行的。