2011-01-10 9 views

Antwort

5

endete ich mit der folgenden Implementierung bis:

(defn protocol? [maybe-p] 
    (boolean (:on-interface maybe-p))) 

(defn all-protocols [] 
    (filter #(protocol? @(val %)) (ns-publics *ns*))) 

(defn implemented-protocols [sym] 
    (filter #(satisfies? @(val %) sym) (all-protocols))) 

Zuerst sieht es für alle Symbole im aktuellen Namensraum (Sie natürlich dies für alle Namensräume erweitern können), ob sie Protokolldefinitionen oder net sind (alle -Protokolle). Als nächstes sucht es nach einem gegebenen Symbol, wenn es eines dieser Protokolle erfüllt.

Das Protokoll? Funktion verwendet die: On-Interface-Taste, die nicht dokumentiert ist afaik, also diese Funktion ist nicht tragbar.

+0

'Protokoll?' Scheitert auf einer sortierten Karte, zumindest in Clojure 1.8. Siehe [diese Frage] (http://stackoverflow.com/q/37410580/1393162). –

0

Ich kann dies derzeit nicht wirklich versuchen, aber Sie könnten versuchen, die Java-Klassenmethode: getGenericInterfaces. Dies sollte Ihnen eine Liste von Schnittstellen geben. Es gibt wahrscheinlich andere Möglichkeiten, diese Informationen mit ähnlichen Methoden zu erhalten, aber ich habe nicht gesucht.

Wenn Sie sich auch den Quellcode ansehen, sehen Sie, wie Protokolle eingerichtet werden (Sie können zur Quelle gelangen, indem Sie auf die Links in der Clojure API klicken). In Clojure 1.3 gibt es eine ‚private‘ Funktion, die wie folgt aussieht:

(defn- protocol? 
    [maybe-p] 
    (boolean (:on-interface maybe-p))) 

Diese Funktion wird durch die Clojure extend Funktion verwendet wird, um zu überprüfen, dass Sie tatsächlich ein Protokoll zur Verfügung gestellt haben. Wenn Sie Ihre eigene Funktion so machen, können Sie die Ergebnisse von getGenericInterfaces filtern. Da dies ein internes Detail ist, kann es Änderungen geben.

+0

getGenericInterfaces gibt mir (clojure.lang.IObj clojure.lang.ILookup clojure.lang.IKeywordLookup clojure.lang.IPersistentMap java.util.Map java.io.Serializable) aber nicht das implementierte Protokoll. Ich denke, ich muss mich in den Quellcode vertiefen, um zu sehen, wie es gemacht wird. –

+0

Bin gerade zurück zu meiner Maschine, und ich komme nicht weiter als du bist. Es ist wahrscheinlich einfacher, getInterfaces als eine vernünftige Alternative zu getGenericInterfaces zu verwenden. Ich frage mich, was passiert, wenn Sie das Ding kompilieren. – hutch

+2

Teil der Protokollen ist, dass eine Klasse keine Schnittstelle implementieren muss, um ein Protokoll zu erweitern: Sie können Ihr eigenes Protokoll definieren und dann sagen, dass eine bereits existierende Klasse es erweitert mit '(extend ExistingClass MyProtocol ...)'. Daher ist es naheliegend, zu fragen, "welche Klassen dieses Protokoll erweitern", aber keine Möglichkeit, die umgekehrte Frage zu stellen. –

Verwandte Themen