Syntax Clojure.core源代码:为什么~@(unquote剪接运算符)内有双引号列表,而不是~(unquote运算符) 序言

Syntax Clojure.core源代码:为什么~@(unquote剪接运算符)内有双引号列表,而不是~(unquote运算符) 序言,syntax,clojure,core,convention,Syntax,Clojure,Core,Convention,我在clojure.core中查看源代码,没有特别的原因 我开始阅读defmacro ns,以下是节选的源代码: (定义宏) “…文档字符串…” {:arglists'([name docstring?attr map?references*]) :添加了“1.0”} [姓名和参考资料] (让。。。 ;这里是参数处理。 名称元数据(元名称)] `(做 (clojure.core/in-ns'~name) ~@(当名称为元数据时) `(.resetMeta(clojure.lang.Namespa

我在
clojure.core
中查看源代码,没有特别的原因

我开始阅读
defmacro ns
,以下是节选的源代码:

(定义宏)
“…文档字符串…”
{:arglists'([name docstring?attr map?references*])
:添加了“1.0”}
[姓名和参考资料]
(让。。。
;这里是参数处理。
名称元数据(元名称)]
`(做
(clojure.core/in-ns'~name)
~@(当名称为元数据时)
`(.resetMeta(clojure.lang.Namespace/find'~name)~name元数据)))
(带加载上下文)
~@(当gen类调用时(列出gen类调用))
~@(当(和(不=name'clojure.core)(不包括任何?#(=:refere clojure(first%))引用))
`((clojure.core/reference'~'clojure.core)))
~@(映射过程引用))
(如果(.equals'~name'clojure.core)
无
(do(dosync(通勤#'*加载的libs*conj'~name))nil(##')))
仔细看 然后试着读它,我看到了一些奇怪的宏模式,特别是我们可以看到:

~@(当命名元数据时)
`(.resetMeta(clojure.lang.Namespace/find'~name)~name元数据)))
clojure.core
版本 以下是宏的独立工作提取:

(让[name metadata]命名元数据
姓名[姓名]
`(做
~@(当名称为元数据时)
`(.resetMeta(clojure.lang.Namespace/find'~name)~name元数据(()()))
=>(do(.resetMeta(clojure.lang.Namespace/find(quote name))名称元数据))
当我运行此命令时,我不禁想知道为什么在
`(.resetMeta
点上有一个双重列表

我的版本 我发现只需删除不带引号的拼接(
~@
)就不需要双重列表。下面是一个独立的工作示例:

(让[name metadata]命名元数据
姓名[姓名]
`(做
~(当命名元数据时)
`(.resetMeta(clojure.lang.Namespace/find'~name)~name元数据)))
=>(do(.resetMeta(clojure.lang.Namespace/find(quote name))名称元数据))
我的问题 因此,clojure.core为什么选择这种看似无关的做事方式

我自己的想法 这是传统的产物吗?
是否还有其他类似的实例以更复杂的方式使用它?

~总是发出一个表单;
~@
可能根本不会发出任何信息。因此,有时使用
~@
有条件地拼接单个表达式:

;; always yields the form (foo x)
;; (with x replaced with its macro-expansion-time value):
`(foo ~x)`

;; results in (foo) is x is nil, (foo x) otherwise:
`(foo ~@(if x [x]))
这就是这里发生的事情:
(.resetMeta…
调用在
do
表单中发出,
ns
仅当
名称元数据
是真实的(非
false
,非
nil


在这种情况下,这并不重要–可以使用
~
,去掉额外的括号,接受没有名称元数据的
ns
表单的宏扩展将在
do
表单中有一个额外的
nil
。不过,为了更美观的扩展,使用
~
并且只使用em是有意义的当名称元数据实际有用时,它是一种处理名称元数据的表单。

您可能希望在Clojure邮件列表中提出以下问题: