我正在尝试创建一个宏,该宏使用注释在Clojure中动态创建Java对象。
我一直在尝试proxy
和reify
,但都没有成功面对CompilerException
。
到此为止:
第一个尝试是创建一个没有宏的对象:
(.toString
(proxy [java.lang.Object] []
(toString [] (str "proxyToString"))))
其结果为:=> "proxyToString"
然后我尝试用一个宏将其包装并传递object
作为参数:
(defmacro create-obj-with-proxy [klass]
`(proxy [~klass] [] (toString [] (str "proxyToString"))))
其结果为:=> #'oppose/create-obj-with-proxy
我可以对其进行扩展或评估
(macroexpand (create-obj-with-proxy java.lang.Object))
(.toString (create-obj-with-proxy java.lang.Object))
它也可以与reify一起使用。
(defmacro create-obj-with-reify [klass]
`(reify ~klass
(toString [this] "reifyToString")))
(macroexpand (create-obj-with-reify java.lang.Object))
(.toString (create-obj-with-proxy java.lang.Object)
但是,如果我将类名与变量关联,则会得到异常
(def give-me-class java.lang.Object)
(def give-me-class-fn [] java.lang.Object)
(.toString (create-obj-with-proxy give-me-class))
(.toString (create-obj-with-proxy (give-me-class-fn)))
(.toString (create-obj-with-proxy give-me-class))
CompilerException java.lang.ClassCastException: clojure.lang.Var cannot be cast to java.lang.Class, compiling:
(.toString (create-obj-with-proxy (give-me-class-fn)))
CompilerException java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol, compiling:
有什么建议吗?
编辑:感谢@Michiel Borkent修复了对象创建问题。
答案 0 :(得分:1)
您快到了,但是需要删除拼接运算符:
(defmacro create-obj-with-proxy [klass]
`(proxy [~klass] [] (toString [] (str "proxyToString"))))
然后
(create-obj-with-proxy java.lang.Object)
将返回
#object[dre.compress.proxy$java.lang.Object$ff19274a 0x6c221bc8 "proxyToString"]
您正在传递符号自变量。使用unquote-splice,您尝试将其视为一个序列,该序列将不起作用,因此会出现错误。