在clojure中创建对象的宏

在clojure中创建对象的宏,clojure,macros,Clojure,Macros,我正在尝试创建一个宏,该宏使用注释在Clojure中动态创建java对象 我一直在尝试代理和具体化,但在面对编译器异常时没有成功 以下是我们所得到的: 代理 第一次尝试是创建没有宏的对象: (.toString (proxy [java.lang.Object] [] (toString [] (str "proxyToString")))) 其结果为:=>proxyToString 然后我尝试用宏包装它,并将对象作为参数传递: (defmacro crea

我正在尝试创建一个宏,该宏使用注释在Clojure中动态创建java对象

我一直在尝试代理和具体化,但在面对编译器异常时没有成功

以下是我们所得到的:

代理 第一次尝试是创建没有宏的对象:

(.toString 
  (proxy [java.lang.Object] [] 
    (toString [] (str "proxyToString"))))
其结果为:=>proxyToString

然后我尝试用宏包装它,并将对象作为参数传递:

(defmacro create-obj-with-proxy [klass]
  `(proxy [~klass] [] (toString [] (str "proxyToString"))))
其结果为:=>'反对/创建带有代理的obj

我可以扩展或评估它

(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,修复了对象创建问题。

您就快到了,但需要删除拼接操作符:

(defmacro create-obj-with-proxy [klass]
  `(proxy [~klass] [] (toString [] (str "proxyToString"))))
然后

会回来的

#object[dre.compress.proxy$java.lang.Object$ff19274a 0x6c221bc8 "proxyToString"]

您正在传入一个符号参数。使用unquote-splice,您试图将其视为一个序列,但该序列不起作用,因此会出现错误。

谢谢,它起作用了!如果我将java.lang.Object提取为函数或def,我会得到空指针异常:/def给我类java.lang.Object def给我类fn[]java.lang.Object.toString使用代理创建obj给我类。toString使用代理创建obj给我类fn当您使用代理创建obj求值时,符号foo必须求值为类。给我类不是一个类的符号,这就是为什么上面不起作用。因此,您将得到一个类似java.lang.ClassCastException的错误:clojure.lang.Var不能转换为java.lang.Class。有没有办法将结果转换为类?我试过类给我类宏不首先计算它们的参数,就像函数一样。看看你要写的东西的宏扩展,我希望应该很清楚。我已经尝试过使用代理[klass]proxy[~class klass][]toString[]str proxyToString`和使用代理[klass]proxy[~class~klass][]toString[]defmacro创建objstr proxyToString`两者都导致编译器异常java.lang.ClassCastException:java.lang.Class无法强制转换为clojure.lang.Symbol,
#object[dre.compress.proxy$java.lang.Object$ff19274a 0x6c221bc8 "proxyToString"]