Ich muss bestimmte Clojure-Funktionen irgendwie als "speziell" markieren, damit der Java-Code sie als solche durch Reflexion erkennen kann. Ich habe versucht, einer Funktion eine Anmerkung hinzuzufügen, aber anscheinend wird das nicht unterstützt. Ich habe versucht, reify
eine Schnittstelle zu erweitern IFn
(so dass der Java-Code das Funktionsobjekt erkennen konnte), aber das ist nicht gut, weil Clojure nicht direkt die verdinglichte Methode als den Code verwendet, der invoke
implementiert, aber eher ein indirekter Aufruf an ein Objekt Afunction
, das die Methode tatsächlich implementiert (ich muss die tatsächliche Methode invoke
mit dem tatsächlichen Funktionscode versehen).
Irgendwelche Ideen?
BEARBEITEN: Selbst das Markieren auf eine Weise, auf die mit der ASM-Bibliothek zugegriffen werden könnte (anstatt regulärer Reflektion) wäre in Ordnung, aber ich muss irgendwie das tatsächliche AFunction
-Objekt oder die invoke
-Methode markieren. Außerdem kann ich nicht auf das tatsächliche AFunction
-Objekt zugreifen - ich brauche das Tag, um in der Klasse sichtbar zu sein.
Sie können die clojure-Metadatenfunktion verwenden, die das Anhängen von Metadaten (einer Karte) an jedes Objekt ermöglicht, das IMeta
Schnittstelle (was sich als jedes Objekt herausstellt, wenn IObj IMeta erweitert und jedes Objekt IObj erweitert)
Jetzt gibt es 2 Möglichkeiten.
1) Sie können die Metadaten an eine Variable anhängen (die Variable verweist auf das tatsächliche IFn-Objekt)
%Vor%und auf Java-Seite erhalten Sie die var hallo und verwenden Sie IMeta-Methoden, um die Metadaten zu erhalten und festzustellen, ob Ihre spezifischen Metadaten da sind oder nicht. Das Problem damit könnte sein, dass Ihr Java-Code IFn-Objekte direkt und nicht ihre Vars (zB: anonyme Funktionen) verwendet. Um dies zu lösen, versuchen Sie die 2. Option.
2) Hängen Sie die Metadaten an das Funktionsobjekt selbst an:
%Vor% Sie können defn
nicht verwenden, um Metadaten an die Variable anzuhängen. Der obige Beispielcode hängt die Metadaten an das Funktionsobjekt selbst an. Auf Java-Seite geben Sie das Funktionsobjekt an IMeta und führen Sie die Überprüfung durch.
Der obige Code kann mit Hilfe eines Makros, das als Übung übrig bleibt, etwas mehr defn
likish gemacht werden:)
Es stellt sich heraus, dass wenn Sie den Funktionskörper mit einer let-Anweisung umschließen, die eine lokale Definition enthält, wird dieser Variablenname in der lokalen Tabelle der Methode in der Klassendatei angezeigt. Ein bisschen umständlich, obwohl. Immer noch auf der Suche nach einem besseren Weg.
Tags und Links clojure clojure-java-interop