为什么要使用阅读器宏#'?

时间:2017-08-15 15:11:45

标签: clojure

我真的不明白这个宏是什么。

(def n 12)
=> #'lambda.core-test/n
#'n
=> #'lambda.core-test/n
(= #'n n)
=> false
(= #'n #'n)
=> true
(= 12 #'n)
=> false

我在某处看到#'x(var x)相同,所以

(var n)
=> #'lambda.core-test/n
(var-get (var n))
=> 12

人们似乎在重新评估时使用它,符号的定义在REPL中不起作用。

这个宏究竟是什么以及它与重新评估有什么关系?

1 个答案:

答案 0 :(得分:7)

#'x只是(var x)

的简写

https://clojuredocs.org/clojure.core/var

http://clojure.org/special_forms

你要使用其中任何一个的原因是你想要引用变量本身而不是存储在变量中的值。例如,您可能希望编写一个doc生成器,用于从一组vars中提取docstrings,arglists和其他元信息。为此,您可以使用:

(def some-var "With a docstring" 1)
(meta (var some-var)) ;; or
(meta #'some-var)

我经常将此阅读器宏与Stuart Sierra的组件库结合使用。 https://github.com/stuartsierra/component

例如,在定义一个新系统(使用组件lib)之后,我经常需要对定义的系统进行一些有状态的突变来启动或停止它。不是引用var x中定义的不可变值,对它起作用,然后返回一个新的不可变值y,我想更新var x的值,改变实际的var x本身。这是一个代码示例。

(require 'com.stuartsierra.component)
(def x (new-system))
(alter-var-root #'x com.stuartsierra.component/start)

https://clojuredocs.org/clojure.core/alter-var-root

大多数clojure开发人员在日常工作中都不会触及这个读者宏,但绝对值得掌握。希望这有帮助!