Clojure defmacro 丢失元数据 [英] Clojure defmacro loses metadata
问题描述
我正在尝试创建一个小 Clojure 宏,它 def
是一个带有类型提示的字符串:
I am trying to create a little Clojure macro that def
s a String with a type hint:
(defmacro def-string [name value]
`(def ^String ~name ~value))
(def-string db-host-option "db-host")
当我macroexpand
它时,类型提示丢失了:
When I macroexpand
it, the type hint is lost:
(macroexpand '(def-string db-host-option "db-host"))
;=> (def db-host-option "db-host")
不要介意暗示这一点的类型的智慧.
Never mind the wisdom of type hinting this.
为什么宏会丢失元数据?如何编写此宏或任何包含元数据的宏?
Why is the macro losing the metadata? How do I write this macro, or any that includes metadata?
推荐答案
^
是一个阅读器宏.defmacro
永远不会看到它.提示放在列表 (unquote name)
中.例如将 (meta ^String 'x)
与 (meta ' ^String x)
进行比较以查看效果.
^
is a reader macro. defmacro
never gets to see it. The hint is put on the list (unquote name)
. Compare for example (meta ^String 'x)
with (meta ' ^String x)
to see the effect.
您需要将提示放在符号上.
You need to put the hint on the symbol.
(defmacro def-string
[name value]
`(def ~(vary-meta name assoc :tag `String) ~value))
以及用法:
user=> (def-string foo "bar")
#'user/foo
user=> (meta #'foo)
{:ns #<Namespace user>, :name foo, :file "NO_SOURCE_PATH", :line 5, :tag java.lang.String}
这篇关于Clojure defmacro 丢失元数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!