21

我正在尝试生成一些带有类型提示的 Clojure 代码,但是每当我构建一些代码时,类型提示似乎就会消失(编译代码时它们也不起作用)

例如

`(let [^BufferedImage b (create-buffered-image)] 
   (.getRGB b 0 0))

=> (clojure.core/let [user/b (user/create-buffered-image)] (.getRGB user/b 0 0))

我不确定为什么类型提示会消失,但我认为这与读者如何处理元数据有关。

在生成的代码中创建正确类型提示的正确方法是什么?

4

1 回答 1

34

这个问题有两个答案。回答您的具体问题:在您刚刚发布的实际代码中,没有任何问题:它工作得很好。(set! *print-meta* true)再试一次,你会看到元数据注释。它只是通常不会打印。

但是,一般来说,这不是从宏做事的正确方法,不久你就会遇到麻烦。请记住,您不需要宏计算的表单上的元数据,您需要宏发出的表单上的元数据。因此,更准确的解决方案是with-meta在您想要将元数据附加到的符号或表单上使用 - 或者,如果它们是用户提供的表单,您通常应该使用vary-meta这样您就不会丢弃他们明确添加的元数据。例如,

(defmacro with-image [name & body]
  (let [tagged-name (vary-meta name assoc :tag `BufferedImage)
    `(let [~tagged-name (create-buffered-image)
       ~@body)))

(with-image i (.getRGB i 0 0))
于 2012-08-12T05:52:07.443 回答