Clojureには、gen-class、reify、proxy、さらにdeftypeとdefrecordがあり、新しいクラスのようなデータ型を定義します。構文の単純さを重視し、不必要な複雑さを嫌う言語の場合、それは異常なようです。なぜそうなのか誰かが説明できますか?一般的なLISPスタイルのdefclassで十分ですか?
これは、3つの異なる要因の組み合わせです。
まず、これらが何をするかを考えてみましょう。 deftypeとgen-classは、どちらも名前付き事前コンパイル用のクラス。 Gen-classが最初に来て、その後clojure 1.2のdeftypeが続きました。 Deftypeが推奨され、パフォーマンス特性は優れていますが、より制限的です。 deftypeクラスはインターフェイスに準拠できますが、別のクラスから継承することはできません。
Reifyとproxyの両方を使用して、匿名のインスタンスが動的に作成されます実行時のクラス。プロキシが最初に来て、reifyはclojure 1.2のdeftypeとdefrecordと一緒に来ました。 deftypeと同様に、意味が制限されないReifyが推奨されます。
同時に出現したdeftypeとdefrecordの両方がなぜ同じような役割を果たしているのか、という疑問が残ります。ほとんどの目的のために、私たちはdefrecordを使用したいと思います。それは、私たちが知っており、愛しているさまざまなクロジュールの良さ、順序性などを備えています。 Deftypeは、他のデータ構造を実装するための低レベルのビルディングブロックとして使用することを目的としています。通常のclojureインターフェースは含まれていませんが、可変フィールドのオプションがあります(これはデフォルトではありません)。
さらに読むためにチェックアウト:
簡単に言えば、それらにはすべて異なる有用な目的があるということです。複雑なのは、基盤となるJVMのさまざまな機能と効果的に相互運用する必要があるためです。
Java interopが必要ない場合は、99%の確率でいずれかのdefrecordを使用することをお勧めしますまたは単純なClojureマップ。
ニーズがより複雑な場合、次のフローチャートは、これらのオプションの1つを他のオプションよりも選択する理由を説明するための優れたツールです。
http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/