Clojure defmacro丢失元数据 [英] Clojure defmacro loses metadata

查看:173
本文介绍了Clojure defmacro丢失元数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个小的Clojure宏 def sa类型提示的字符串:

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

(def-string db-host-option db-host)



当p macroexpand 它,类型提示丢失:

 (宏展开式(def-string db-host-optiondb-host) )
; => (def db-host-optiondb-host)

不介意类型提示的智慧。



为什么宏丢失元数据?如何写这个宏或包含元数据的任何内容?

解决方案

^ 是读取器宏。 defmacro 永远不会看到它。提示放在列表(unquote name)上。比较例子(meta ^ String'x)(meta'^ String x)才能看到效果。 / p>

您需要在符号上加上提示。

 (defmacro def-string 
[name value]
`(def〜(vary-meta name assoc:tag`String)〜value))

而用法:

  user => (def-string foobar)
#'user / foo
user => (meta#'foo)
{:ns#< Namespace user> ;,:name foo,:fileNO_SOURCE_PATH,:line 5,:tag java.lang.String}


I am trying to create a little Clojure macro that defs a String with a type hint:

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

(def-string db-host-option "db-host")

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?

解决方案

^ 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))

And the usage:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆