Clojureには、genクラス、reify、proxy、deftypeおよびdefrecordがあり、新しいクラスのようなデータ型を定義します。構文の単純さと不必要な複雑さを嫌う言語の場合、それは収差のように思えます。 誰かがなぜそうなのか説明できますか? Common Lispスタイルのdefclassで十分でしょうか?Clojureは、クラスを1つではなく5つの方法で定義する理由は何ですか?
答えて
これは、3つの異なる要因の組み合わせである:
- これらは早期に開発され、言語の進化に伴って後に開発されました。
まず、これらが何をするかを考えてみましょう。 deftypeおよびgen-classは、両方とも、事前コンパイルのための名前付きクラスを定義している点で類似しています。ジェネラルクラスが最初に来て、clojure 1.2でdeftypeが続きました。 Deftypeが好まれ、パフォーマンス特性は優れていますが、より制限的です。 deftypeクラスはインタフェースに準拠できますが、別のクラスから継承することはできません。
具体化とプロキシは、両方の実行時に動的に匿名クラスのインスタンスを作成するために使用されています。プロキシが最初に来て、refeはdeftypeとdefrecord with clojure 1.2と一緒に来ました。セマンティクスがあまり制限的ではない、デフトタイプと同じように、Reifyが好まれます。
deftypeとdefrecordの両方が同じ時刻に表示され、同様の役割を果たしているため、その理由が問われます。ほとんどの目的のために、私たちはdefrecordを使いたいと思っています。それは、われわれが知っていて愛しているさまざまな善良さ、順序性などすべてを持っています。 Deftypeは、他のデータ構造を実装するための低レベルビルディングブロックとしての使用を意図しています。通常のclojureインターフェイスは含まれていませんが、これはデフォルトではありませんが、変更可能なフィールドのオプションがあります。
さらに読書のためにチェックアウト:
The clojure.org datatypes page
The google group thread where deftype and reify were introduced
短い答えは、彼らがすべて異なると有用な目的を持っているということです。複雑さは、基盤となるJVMのさまざまな機能と効果的に相互運用する必要があるためです。
の場合、Javaの相互運用性は不要です。時間の99%は、defrecordまたは単純なClojureマップを使用することをお勧めします。
- 使用defrecordあなたは、そうでない場合のプロトコル を使用したい場合は、通常のClojureのマップで、おそらく最も簡単で理解しやすい
ニーズがより複雑な場合は、次のフローチャートは、のための素晴らしいツールです。あなたが他の人の上にこれらのオプションのいずれかを選択する理由を説明する:
http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/
フローチャートへのリンクに感謝します。このブログは、O'reilly's - Programming Clojureの共著者によるものです。私はこの意思決定がかなり複雑だと思う。インタフェースと具象クラスの違いや静的メソッドの定義の必要性、または名前付きの型や匿名型は膨大なため、異なる言語構造が必要ですか? – Salil
違いは広大ではありませんが、達成しようとしている点では哲学的に違いがあります。私はClojureの複数のアプローチがこれらの根本的な違いを反映していると考えています。なぜなら、異なる名前を付けなければならない理由があります。 – mikera
+1。前のフローチャートを見ていなかった、それは素晴らしいです。 –
- 1. 1つのtasks.jsonでいくつかのtypescriptコンパイルタスクを定義する方法は?
- 2. 理由は何ですか:laravel 5
- 3. ディレクティブがクラスを設定しない理由は何ですか?
- 4. Clojure先物を1つのスレッドで実行する方法は?
- 5. 1つの方法が別の方法より効率的な理由は何ですか?
- 6. これが「未定義」を返す理由は何ですか?
- 7. Java:このようなキャラクターを定義する理由は何ですか?
- 8. 1つ1つではなく、すべてのエラーを指摘する方法
- 9. Powershellのいくつかのメソッドが定義でインターフェイスを使用する理由
- 10. Retrofitでは、インターフェイスごとに1つの方法を使用する理由
- 11. SQL 1つではなく5つの最大値を見つける
- 12. 1つのクラスで2つのクラスのプロパティを継承する方法は?
- 13. 5つの要素で1つのセットを5つのセットにする方法
- 14. 1つのCSSクラスに複数のスタイルを定義する方法は?
- 15. 「未定義はオブジェクトではない(PropTypes.shapeを評価する)」という理由は何ですか?
- 16. luarocksのロックスペックファイルを管理する良い方法は何ですか?その理由は何ですか?
- 17. パフォーマンスは、シングルトンクラスまたは静的クラスを持つ十分な理由ですか?
- 18. Clojure(Script)でクロスプラットフォームマクロを書く適切な方法は何ですか?
- 19. 2行ではなく、1行に2つの変数を定義する
- 20. __setattr __()は__slots__を持つクラスで定義できますか?
- 21. 私は更新方法を使用できない理由は何ですか?
- 22. ではなく、1つの
- 23. anglejsでカスタムディレクティブを定義する方法はいくつありますか?
- 24. Spring MVCでModelクラス(model.addAttribute())を使う理由は何ですか?
- 25. Clojureでマップをスライスする慣用方法は何ですか?
- 26. 関数return element.innerHTMLまたはelement.innerTextが未定義の理由は何ですか?
- 27. Flumeメモリチャネルはいつ復元可能ではないのですか?その理由は何ですか?
- 28. 関数定義とクラス定義の違いは何ですか
- 29. 1行で簡単にインスタンス化できるプライベートメンバーを持つクラスを定義する最も良い方法は?
- 30. 5つではなく4つのdivを1つの行に表示するだけです
Googleグループのスレッドは非常に貴重でした。私の理解は、java-interopプロキシのためであり、gen-classはreifyとdeftypeを主に取り入れています。私は今、タイプを定義するための「推奨される」方法が少なくなったことをうれしく思っています。 – Salil
偉大な答えは、スレッドのリンクに感謝します。 –
申し訳ありませんが、「連続性」とはどういう意味ですか? Googleがサポートしていない... – Trylks