pro*_*ron 8 clojure clojure-java-interop
我需要以某种方式将某些Clojure函数标记为"特殊",以便Java代码可以使用反射识别它们.我试图在函数中添加注释,但显然不支持.我试图reify扩展接口IFn(以便Java代码可以识别函数对象),但这并不好,因为Clojure不直接使用reified方法作为代码实现invoke,而是间接调用Afunction实际的对象实现该方法(我需要invoke用实际的功能代码标记实际的方法).
有任何想法吗?
编辑:甚至以可以使用ASM库(而不是常规反射)访问的方式进行标记也没问题,但我需要以某种方式标记实际AFunction对象或invoke方法.此外,我无法访问实际AFunction对象 - 我需要标记在类上可见.
您可以使用 clojure 元数据功能,该功能允许将元数据(映射)附加到实现接口的任何对象IMeta(结果是每个对象,因为 IObj 扩展 IMeta 并且每个对象扩展 IObj)
现在有2个选择。
1)您可以将元数据附加到var(var指向实际的IFn对象)
(defn hello {:name "hello"} [] 10)
Run Code Online (Sandbox Code Playgroud)
在 Java 方面,您可以使用 var hello 并使用 IMeta 方法来获取元数据并检测您的特定元数据是否存在。问题可能是您的 Java 代码直接访问/处理 IFn 对象而不是它们的变量(例如:匿名函数),要解决此问题,请尝试第二个选项。
2) 将元数据附加到函数对象本身:
(def hello (with-meta (fn [] 10) {:name "hello"}))
Run Code Online (Sandbox Code Playgroud)
您不能使用defnas 将元数据附加到 var。上面的示例代码将元数据附加到函数对象本身。在 Java 端,将函数对象键入 IMeta 并进行检查。defn借助宏可以使上面的代码变得更可爱一点,这作为练习:)