鉴于下面的宏 -
(defmacro defhello [fn-name body] `(defn ~fn-name [~'name] ~body))
Run Code Online (Sandbox Code Playgroud)
和被称为 - 时定义的函数 -
(defhello问候语(str"你好"的名字))
并称为
(问候"乔")
, 将返回
Hello Joe
我不明白在name参数前面的〜'的用法?它有什么作用?不引用(')和取消引用(〜)相互取消?当它们一起使用时会发生什么?为什么不在没有它们的情况下写名?
简而言之,~就像它所做的那样,在语法引用的表单中计算表达式~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不存在另一个函数.