3

プログラムで指定したフィールドに変更を加える場合、Erlangでレコードを(コピーして)変更する比較的簡単な方法はありますか?

例えば:

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

modify_record(Record, Field, Value) ->
  Record#my_record{Field = Value}.

modify_record(#my_record{foo = 1}, bar, 42)、または、のようなことをすることができるようにmodify_record(some_method_that_returns_a_my_record(), foo, 3.14)

そのようなものをコンパイルすると、次のようなエラーが発生します

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

プロップリストとの間で変換する方法についていくつかの例があることを私は理解していますが、私はもっと簡単なものを望んでいました。

4

4 に答える 4

5

(フィールド名ではなく) フィールド番号を渡せば可能です。関数を呼び出すことを意味します

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).
于 2012-11-02T15:08:20.613 に答える
4

次のように機能させることができます:

modify_record(Record, Field, Value) ->
 case Field of 
   foo -> Record#my_record{foo = Value},
   bar -> Record#my_record{bar = Value}
 end.
于 2012-11-02T03:04:00.270 に答える
3

https://github.com/jcomellas/mlapi/blob/master/src/dynarec.erlの「dynarec」のようなものを使用できます

モジュールでは、先頭に以下を含めて解析変換を指定する必要があります。

-compile({parse_transform, dynarec}).

この解析変換は、そのモジュールに定義または含まれるすべてのレコードのセッターとゲッターを挿入することにより、コンパイル時にモジュールを変更します。

つまり、次のようなことができます。

NewRecord = set_value(field_name, Value, Record)

より完全な例が含まれているため、dynarec の上部にあるコメントを読むことをお勧めします。

それが役立つことを願っています。

于 2012-11-02T03:01:26.453 に答える
2

レコードは純粋にコンパイル時であるため、すべてがコンパイル時に認識されている必要があります。これは、実行時にフィールド名を計算できないことを意味します。これは、実行したいことです。@ligaoren と @chops によって提供されるメソッドは、これを処理する 2 つの方法ですが、ご覧のとおり、どちらもコンパイル時に処理を行います。

于 2012-11-02T14:08:18.990 に答える