Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.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
Clojure 什么是';作为前缀添加到宏中的变量时暗示_Clojure - Fatal编程技术网

Clojure 什么是';作为前缀添加到宏中的变量时暗示

Clojure 什么是';作为前缀添加到宏中的变量时暗示,clojure,Clojure,鉴于下面的宏- (defmacro defhello [fn-name body] `(defn ~fn-name [~'name] ~body)) 以及在调用时定义为- (defhello问候语(str“Hello”name)) 并称为 (问候“乔”) ,将返回 你好,乔 我不明白name参数前面的~'的用法是什么?它有什么作用?不引用(')和取消引用(~)会相互取消吗?当它们一起使用时会发生什么?为什么不直接写名称而不写它们呢?据我所知,您引用了函数定义,因此在定义宏时不会对其求值。使

鉴于下面的宏-

(defmacro defhello [fn-name body]   `(defn ~fn-name [~'name] ~body))
以及在调用时定义为-

(defhello问候语(str“Hello”name))

并称为

(问候“乔”)

,将返回

你好,乔


我不明白name参数前面的~'的用法是什么?它有什么作用?不引用(')和取消引用(~)会相互取消吗?当它们一起使用时会发生什么?为什么不直接写名称而不写它们呢?

据我所知,您引用了函数定义,因此在定义宏时不会对其求值。使用unquote运算符
~
,计算定义中的名称。如果名称是一种列表,
~@
(unquote splice)将计算列表中没有括号的元素。

简而言之,
~
以语法引号形式计算表达式,就像它对
~fn name
一样。在这种情况下,要计算的表达式是
'name
,其中结果是非限定符号
name

但是,让我们一次分解一部分

如果您只有非限定符号
name
,则在运行时它将被计算为
clojure.core/name
。这将导致不正确的
defn
表单,并导致编译器异常

(defn greeting [clojure.core/name] (str "Hello" name)) 
(defn greeting [(quote clojure.core/name)] (str "Hello" name))
如果您只引用了非限定符号
“name
,它仍将在运行时进行计算。区别在于它将扩展到
(quote clojure.core/name)
。同样,这将导致不正确的
defn
表单,并导致编译器异常

(defn greeting [clojure.core/name] (str "Hello" name)) 
(defn greeting [(quote clojure.core/name)] (str "Hello" name))
最后,通过使用
~'name
,您将在编译时对引用的表单进行求值,从而得到不合格的符号
name
,从而为您留下一个正确的
defn
表单

(defn greeting [name] (str "Hello" name))
1-对于本例,这是正确的,因为它假定另一个
名称
函数不存在。

名称前的引号用于防止符号限定

如果您不知道什么是资格赛,请参阅

此外,还可以用于宏调试


如果你想更多地了解宏,我建议你阅读。也许有点难,但这让你知道宏是如何工作的。

这个例子是从哪里来的?我写的。工作如期进行。但是~'只是反复试验,所以想知道它为什么会起作用。1)为什么它将符号计算为clojure.core/name ns,而不是当前的ns?这是所有符号解析的默认行为吗?不是。它正在评估符号
name
clojure.core/name
,因为该函数已经存在并且在范围内。(
clojure.core
默认情况下提供。)此外,单引号不限定名称空间,而语法引号限定名称空间。公共Lisp宏与clojure宏有细微的不同。