在宏中添加为变量的前缀时,暗示了什么?

mur*_*a52 11 clojure

鉴于下面的宏 -

(defmacro defhello [fn-name body]   `(defn ~fn-name [~'name] ~body))
Run Code Online (Sandbox Code Playgroud)

和被称为 - 时定义的函数 -

(defhello问候语(str"你好"的名字))

并称为

(问候"乔")

, 将返回

Hello Joe

我不明白在name参数前面的〜'的用法?它有什么作用?不引用(')和取消引用(〜)相互取消?当它们一起使用时会发生什么?为什么不在没有它们的情况下写

Jer*_*emy 9

简而言之,~就像它所做的那样,在语法引用的表单中计算表达式~fn-name.在这种情况下,要评估的表达式是'name,其中结果是非限定符号name.

但是,让我们一次打破一件.

如果您只有非限定符号name,则会clojure.core/name在运行时1进行评估.这将导致不正确的defn表单并导致编译器异常.

(defn greeting [clojure.core/name] (str "Hello" name)) 
Run Code Online (Sandbox Code Playgroud)

如果您只有引用的非限定符号'name,它仍将在运行时进行评估.不同之处在于它会扩展到(quote clojure.core/name).同样,这将导致不正确的defn形式并导致编译器异常.

(defn greeting [(quote clojure.core/name)] (str "Hello" name))
Run Code Online (Sandbox Code Playgroud)

最后,通过使用~'name,您将在编译时评估引用的表单,从而产生不合格的符号name,为您留下适当的defn表单.

(defn greeting [name] (str "Hello" name))
Run Code Online (Sandbox Code Playgroud)

1 - 这个例子的确如此,因为它假设name不存在另一个函数.