私はclojureプログラムで多くのマップと構造体を使用しています。これらをdefrecordsに変換することの利点(パフォーマンスは別として)は何ですか?clojureでどこでdefrecordを使うべきですか?
答えて
私は全く利用していないので、構造体を効果的に廃止されると考えています。
多くのマップインスタンスで使用されている固定キーセットが固定されている場合、通常はレコードを作成します。大きな利点は次のとおりです。
- パフォーマンス
- 生成されたクラスは、私がdefrecord周りに追加のマクロ機械でマルチメソッドまたはその他の状況
- にオンに切り替えることができますタイプを持って、私はフィールド検証を得ることができ、デフォルト値、および私はほとんどの目的
- キーとヴァルス用のマップは、(安定にPEを結果を返すよう
- レコードは、任意のインターフェイスまたはプロトコルを実装することができます(マップはできません)
- レコードが行動したいものは何でも他のものR-作成)ため
レコードのいくつかの欠点:
- レコードは、Javaクラスのインスタンス(ないClojureのマップ)であるため、構造的共有はありません同じレコード構造ので、おそらくより多くのメモリを使用します。変更された同等のマップ構造。 JVMは、この種の短命のゴミを特別な汗をかくことなく食べるように設計されていますが、レコードを "変更"するとオブジェクトの作成/破棄も増えます。
- 開発中にレコードを変更する場合は、REPLを頻繁に再起動して変更を取得する必要があります。これは通常、開発の幅が狭い場合にのみ問題になります。
- 既存のライブラリの多くは、レコードをサポートするように更新されていません(ポストウォーク、ジップ、マッチャーなど)。必要に応じてこのサポートを追加しました。
他の大きな利点の1つは、レコードがあなたがディスパッチできるタイプ(そのクラス)を持っていることです。
この機能を使用していますが、すべての可能な用途の代表ではない例は以下の通りです:
(defprotocol communicate
(verbalize [this]))
(defrecord Cat [hunger-level]
communicate
(verbalize [this]
(apply str (interpose " " (repeat hunger-level "meow")))))
(defrecord Dog [mood]
communicate
(verbalize [this]
(case mood
:happy "woof"
"arf")))
(verbalize (->Cat 3))
; => "meow meow meow"
(verbalize (->Dog :happy))
; => "woof"
実際には、タイプだけでなく、どのような関数でもディスパッチすることができます。普通のマップを使って、 "type"という名前のキーを持つ別のエントリを追加することができます。次に、 "type"エントリの値をチェックするディスパッチ関数を使用することができます。 –
@Goran、これはマルチメソッドに適用され、プロトコルを使用すると、タイプ上でのみディスパッチできます。それにもかかわらず、defrecordsを使用している点では、defstructまたはmapが型を自動的に追加しない間に型を暗黙的に追加しています。 – bmillare
この回答は本当に簡潔です。例がいいかもしれません。 – matanster
スチュアート・シエラは最近もdefrecord
のセクションが含まれている、「Clojureの1.2と式問題の解決」に興味深い記事を書いた:
http://www.ibm.com/developerworks/java/library/j-clojure-protocols/index.html#datatypes
私は全体の記事が良い出発だと思いますプロトコルと記録を理解するためのポイント。
これはリンクのみの回答です。それは少なくとも要約を必要とする。 – MasterMastic
ほとんどの場合、マップを使用し、多型性が必要な場合のみ記録します。マップだけでも、マルチメソッドを使用することができます。ただし、プロトコルが必要な場合はレコードが必要です。これを考えると、レコードに頼る前にプロトコルが必要になるまで待ってください。それまでは、より多くのデータ中心の単純なコードを使用することを避けてください。
パフォーマンスの面で一般的に同等以上であることに加えて、同じプログラミングインターフェイスをマップとして公開することに加えて、レコードは軽い構造を強制します。キー名とキー数が強制されます定義時に。これは、同じ構造が多くの値から期待される場合(または、人工的に他の方法では堅牢でない場合)、ばかげたエラーを避けるのに役立ちます。
本来の動機が何であれ、このプロパティも地図から離れています。
- 1. Clojureのdefrecord - 使い方は?
- 2. ここではどのイベントを使うべきですか?
- 3. 私はここでどのデザインパターンを使うべきですか
- 4. どこでstd ::とboost :: prefixesを使うべきですか?
- 5. どこで何を使うべきですか? urllibはのpython3
- 6. どこでXSP.endAjaxLoading()を使うべきですか?
- 7. WatiN DomContainerクラスはどこで使うべきですか?
- 8. どこでデータベースを使うべきですか?また、mysqlのどこでテーブルを使用しますか?
- 9. このコードでどのようにマップを適用できますか? (Clojure)
- 10. Clojureでは、マップのすべてのキーをどのように破壊するのですか? Clojureので
- 11. ここでfor文を使うべきでしょうか?
- 12. ここでCUDAを使うべきですか?
- 13. 私は&&または||を使うべきですか?ここで
- 14. ここで.setAdapterを使うべきですか?/ListActivityを拡張しない方法はどうですか?
- 15. log4jでConfigurationまたはLoggerConfigをどこで使うべきですか?
- 16. display:blockを使うべきか、display:flexを使うべきですか?
- 17. アプリケーションを終了するにはどこでfinish()を使うべきですか?
- 18. Wordpressをこのプロジェクトに使うべきですか、ゼロからハンドコードを使うべきですか?
- 19. オープンソースライブラリをWindowsでどのように使うべきですか?
- 20. C#でWMPEqualizerSettingsCtrlClassをどのように使うべきですか?
- 21. WellKnownTypesをC#でどのように使うべきですか?
- 22. 私のコードベースで私のGoogle APIキーはどこで使うべきですか?
- 23. Clojure:別の名前空間でdefrecordが宣言されました
- 24. Clojure defprotocolとdefrecordを組み合わせる
- 25. 名前付きパラメータをdefrecordでクローズしますか?
- 26. XamarinでClojure CLRをC#で使用することはできますか?
- 27. setUpClassはいつ使うべきですか?__init__を使うべきですか?
- 28. Clojureのfnで未定義シンボルを使用するにはどうすればよいですか? Clojureので
- 29. いつこれをメソッドで使うべきですか?
- 30. Clojureのソースコードをどのようにリファクタリングできますか?
あなたの3番目の引数に記述するコンストラクタフォームは、Common Lispが 'defstruct'で定義されたコンサートタイプで使用される引数*の順番で" BOAコンストラクタ " - *を参照するものです。 http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_b.htm#boa_lambda_listを参照してください。 – seh
こんにちはアレックス - 私はあなたがレコードが実際に構造共有を使っていることがわかると思います。彼らは完全な永続的なデータ構造を実装しているので、通常のマップのすべての利点を保ちます。 – mikera
Mikera - レコードは、最終フィールドを持つJavaクラスを生成します。ひとつにまとめることは、新しいJavaオブジェクトを生成する必要があります。フィールドインスタンスは不変なので再利用できますが、通常のClojureマップほど効率的ではありません。 –