使用java对象的clojure宏返回映射的问题

时间:2013-06-20 18:40:52

标签: macros clojure clojure-java-interop

我是非常新的宏,所以我有一个基本的问题,似乎与在Clojure代码中表示Java对象的方式有关。我有一个应该返回地图的宏:

(defmacro g []
  (let [m {:color :black}]
     `(identity ~m)))


user=> (g)
{:color :black}

然而,当我在地图中使用java对象时,事情变得奇怪

(defmacro g []
  (let [m {:color java.awt.Color/BLACK}]
     `(identity ~m)))

 user=> (g)
 CompilerException java.lang.RuntimeException: Can't embed object in code, maybe
 print-dup not defined: java.awt.Color[r=0,g=0,b=0], compiling:(NO_SOURCE_PATH:1
 :1)

如果我将defmacro更改为defn,则输出如下所示:

user=> (g)
(clojure.core/identity {:color #<Color java.awt.Color[r=0,g=0,b=0]>})

所以我猜这种表现方式让读者感到高兴。有没有正确的方法来做到这一点?

2 个答案:

答案 0 :(得分:0)

有几种方法可以写这个,虽然有一种方法可以让我觉得很正确的宏观方法是让它返回一个评估到地图的表格,包括let

user> (defmacro g []
          `(let [m# {:color java.awt.Color/BLACK}]
                 (identity m#)))
#'user/g
user> (g)
{:color #<Color java.awt.Color[r=0,g=0,b=0]>}

这允许从类中解析对象。

答案 1 :(得分:0)

扩展宏时会发生这种情况。

(macroexpand '(g))
;=> (clojure.core/identity {:color #<Color java.awt.Color[r=0,g=0,b=0]>})

请注意Java对象的可读形式如何?