2011-07-08 4 views
6

defrecordによってのみ実装されるプロトコル(defprotocol)を定義したい場合は、最初にプロトコルを定義してから、それを実装するdefrecordを定義する必要があります:Clojure defprotocolとdefrecordを組み合わせる

おそらく "匿名"プロトコルと2つを組み合わせる方法はありませんか?

+1

通常の機能を使用したくない理由はありますか? – Jonas

+0

@Jonas:プロトコルを後で 'defprotocol'にリファクタリングして、他のレコードで実装できるようにしたいのですが、現時点ではわかりません。私はいつもリファクタリングの一部として通常の関数をプロトコル関数に変更できると思います。また、プロトコルを実装せずに 'count'のようなビルトイン関数を「オーバーライド」することはできません。あるいは、デフォルトバインディングをシャドーします。 – Ralph

+1

'count'という名前のプロトコル関数も組み込み関数をシャドウします。 – amalloy

答えて

11

これを行わないでください。レコードが実装する「プライベート」または「匿名」プロトコルは、OOPの無意味なバージョンをより良いオプションを持つ言語で再開発しているだけです。あなたのレコードで動作する通常の古い関数を定義します。物理的にそれらに付ける必要はありません。

後でそれをプロトコルではなくリファクタリングしたい場合は...簡単です!プロトコル関数呼び出しは通常の関数呼び出しのように見えるので、クライアントはその違いを知ることができません。

+0

新しい機能が既存の「コア」機能と同じ場合はどうなりますか?コア機能をシャドーにしませんか?その場合は名前空間を修飾する必要があります。 – Ralph

+0

私/ +対+ –

+0

@ラルフあなたの質問に私のコメントを参照してください。はい、それはコア機能をシャドーしますが、プロトコルも使用します。あなたが本当にそれを匿名にしたければ、その関数をレコードのフィールドとして添付することができます: '(defrecord Foo [count-me])...([x(Foo。(常に1))]] ... ((:count-me x)x)) ' – amalloy

4

はい、それは完全に正しいです:)

後であなたのプロトコルを拡張したいために他人を期待する場合は、この主な理由は次のようになり。

関連する問題