Elixirの実装を書いている時、データを保持したりする時にStructs、String-keyed Maps、Atom-keyed Mapsのどれを使えばいいかよく悩んでいました。今日も悩んでいて、何かベストプラクティスないかな、と考えていたところ、ちょうど私の考えと同じものがあったのでメモ。
それぞれは以下な感じで書くことができます。
iex> %{a: 1, b: 2} # atom
iex> %{"a" => 1, "b" => 2} # string
iex> %Sample{a: 1, b: 2} # Struct
BEAM VMにおいて、atomはCGされません。そのため、どうてきにatomを生成することは良くない、と知っていました。その上で、何が一番妥当なのかなーと思ってたら、以下ページが見つかりました。
https://engineering.appcues.com/2016/02/02/too-many-dicts.html
ルールは以下。
1. Always Use String-Keyed Maps for External Data
2. Convert External Data to Structs ASAP
3. Use Structs in All Other Code
4. Use Structs for Output Data
5. Avoid Using Atom-keyed Maps That Aren’t Structs
6. Use Keyword Lists Only for Function Arguments
Structsで定義していたら、 defprot や defimple する時にそれ用の実装もできますしね。
パッと見ると、動的に生成することのあるデータにはString-keyed Mapsを使う。何かデータを保持してライブラリ外でも使うような場合はさっとStrucsを。atomを使うkeyword listとかStructは残り続ける値として使うとき。
私の感覚と同じでよかった。