2011-12-12 6 views
7

たとえば、2つの異なるレコードを持っていても共通のフィールドをいくつか共有している場合は、両方のレコードが共通の基本レコードを共有する方法はありますか?プロトコルはメソッドシグネチャの宣言のみを可能にするようです。Clojureでデータ型の継承を行うことはできますか?

+0

2つのエンティティがいくつかのフィールドを共有しているということは、それらの間に継承関係を作成するのに十分な理由ではありません。おそらく、いくつかの使用シナリオの例を提供します。 –

+1

たとえば、解析されたSQLクエリを表すためにレコードを使用しています。だから私はSELECT、UPDATE、INSERTなどのレコードを持っています。それらは 'string'プロパティのようないくつかの一般的なプロパティを共有しています。私が多態関数を使ってそれらを扱うとき、私はそれらがすべていくつかの共通の特性を持つことを保証したいと思います。 – Chris

+1

レコードはほんの空想的なマップなので、「すべてのプロパティに共通性があることを確認する」という意味が明確ではありません。なぜ '(:string a-record)'を呼び出せないのですか?また、レコードが持つ可能性のあるキーのセットは、具体的な型が表現できる動作とは異なる問題です。あなたは解決しようとしている実際の問題は何ですか? –

答えて

3

今は可能ではないと思います。

defrecordは単なるマクロであり、あなたはそれがmacroexpandを使って何をするか確認することができ、のようなもの:あなたは、このような記録の継承をしたい場合は

(macroexpand '(defrecord User [Name Age])) 

は、だから、おそらくそうするマクロを実装する必要があります。 しかし、継承は私が避けようとしていることは複雑であるため、これを示唆しません。

3

抽象的なプログラミングではなく、特定のフィールドでプログラミングする必要があります。つまり、レコードが共通のインターフェイスを共有できるようにプロトコルを使用する必要があります。たとえば、すべてのレコードタイプが '文字列'プロパティを返す必要がある場合は、 'get-string'メソッドを使用してプロトコルを作成し、それを各レコードタイプに拡張します。

(defprotocol SQL 
    (get-string [t])) 

(defrecord Thing [name f1 f2] 
    SQL 
    (get-string [t] (str name))) 

(defrecord AnotherThing [name f1 f2 f3 f4 blah] 
    SQL 
    (get-string [t] (str name))) 

あなた自身が特定のプロトコルの方法ことができます常に「defn-」(非公開機能)実装のための同じ実装を作成し、各レコードタイプでの実装としてそれを使用する見つければ。

+1

別のレコードのいくつかのフィールドを共有するレコードを作成したいのですが?そのような場合:(defrecord a [ba bc])(defrecord b [ba bc bd]。 –

関連する問題