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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.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 defmacro丢失元数据_Macros_Clojure_Type Hinting - Fatal编程技术网

Macros Clojure defmacro丢失元数据

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

我正在尝试创建一个小Clojure宏,它
def
s一个带有类型提示的字符串:

(defmacro def-string [name value]
  `(def ^String ~name ~value))

(def-string db-host-option "db-host")
当I
macroexpand
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}

啊!当然,读卡器宏在定义宏之前得到评估。谢谢