Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macros clojure宏返回带有java对象的映射时出现问题_Macros_Clojure_Clojure Java Interop - Fatal编程技术网

Macros clojure宏返回带有java对象的映射时出现问题

Macros clojure宏返回带有java对象的映射时出现问题,macros,clojure,clojure-java-interop,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}] `(

我对宏非常陌生,所以我有一个基本问题,似乎与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]>})
user=>(g)
(clojure.core/identity{:color})

所以我猜这种表现会让读者感到厌烦。有没有正确的方法可以这样做?

有几种方法可以这样写,但我觉得有一种方法是让它返回一个表单,该表单的计算结果是映射,包括
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]>}
user>(定义宏[]
`(让[m#{:color java.awt.color/BLACK}]
(身份m#))
#'用户/g
用户>(g)
{:颜色#}

这允许从类解析对象。

这是宏展开时发生的情况

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

注意Java对象的可读性如何?

我不确定编译器是否在计算周期之间打印并重新读取表单?否则为什么会失败?(我很好奇。)错误消息提到可能没有为对象定义
print dup
。嗯,我为
java.awt.Color
实现了
print dup
,并且在打印扩展宏时似乎没有使用它。当对象“解析”时,这不会改变,在名称空间的意义上:解析都是在读取时在定义宏的名称空间中完成的。不同之处在于,宏不是以某种神奇的方式包括“黑色”,就像我在源代码中键入了黑色的概念一样,而是在运行时将
black
作为类
java.awt.color
中的静态字段进行查找。