Macros Clojure defmacro丢失元数据
我正在尝试创建一个小Clojure宏,它Macros Clojure defmacro丢失元数据,macros,clojure,type-hinting,Macros,Clojure,Type Hinting,我正在尝试创建一个小Clojure宏,它defs一个带有类型提示的字符串: (defmacro def-string [name value] `(def ^String ~name ~value)) (def-string db-host-option "db-host") 当Imacroexpandit时,类型提示丢失: (macroexpand '(def-string db-host-option "db-host")) ;=> (def db-host-option "d
def
s一个带有类型提示的字符串:
(defmacro def-string [name value]
`(def ^String ~name ~value))
(def-string db-host-option "db-host")
当Imacroexpand
it时,类型提示丢失:
(macroexpand '(def-string db-host-option "db-host"))
;=> (def db-host-option "db-host")
不要介意暗示这一点的类型的智慧
为什么宏会丢失元数据?如何编写此宏或任何包含元数据的宏?
^
是一个读卡器宏defmacro
永远看不到它。提示被放在列表中(不引用名称)
。例如,将(meta^String'x)
与(meta'^String x)
进行比较以查看效果
你需要在符号上加上提示
(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}
user=>(定义字符串foo“bar”)
#'用户/foo
用户=>(元#'foo)
{:ns#,:name foo,:file“NO_SOURCE_PATH”,:第5行,:tag java.lang.String}
元数据不会显示在宏扩展中,因为它被认为是“不可见的”
如果宏是正确的(事实并非如此),您应该能够调用(meta#'db-host-option)来检查var上的元数据
注意,(def sym…)在从符号接收的变量上插入元数据。但是^Tag~name在~name(unquote name)上设置元数据,而不是在绑定到name的传入符号上设置元数据。它无法执行任何其他操作,因为^Tag。。。处理由读取器完成,一旦宏展开开始,读取器就已经完成
你想要什么
(defmacro def-string [name value]
`(def ~(with-meta name {:tag String}) ~value))
user> (def-string bar 1)
#'user/bar
user> (meta #'bar)
{:ns #<Namespace user>, :name bar, :file "NO_SOURCE_FILE", :line 1, :tag java.lang.String}
(定义宏定义字符串[名称值]
`(def~(具有元名称{:标记字符串})~value))
用户>(定义字符串栏1)
#'用户/bar
用户>(元#'栏)
{:ns#,:名称栏,:文件“NO_SOURCE_file”,:第1行,:tag java.lang.String}
啊!当然,读卡器宏在定义宏之前得到评估。谢谢