如果'x在clojure中评估为(var x),为什么它们不相等?

mar*_*hon 0 clojure

在O'Reilly的"Clojure编程:Java世界的实用Lisp"中,有一个声明:

var特殊形式执行此操作:

(def x 5)
(var x) 
;= #' user/x 
Run Code Online (Sandbox Code Playgroud)

你现在已经多次看到如何在REPL中打印变量:#',后跟一个符号.这是扩展为对var的调用的读者语法:

 #'x 
 ;= #' user/x
Run Code Online (Sandbox Code Playgroud)

(Kindle Locations 1278-1282).

对此进行测试似乎并非如此.我认为类型类型是相同的.

[user]> (def x 5)
#'user/x

[user]> (= 'x (var x))
false

[user]> (type 'x)
#<Class@c540f5a clojure.lang.Symbol>

[user]> (type (var x))
#<Class@77e9807f clojure.lang.Var>

[user]> 'x
x

[user]> (var x)
#'user/x
Run Code Online (Sandbox Code Playgroud)

Ala*_*son 5

你错过了这个#符号:

(def x 5)
(spyx (var x))
(spyx #'x)

(var x) => #'tst.clj.core/x
(var x) => #'tst.clj.core/x
Run Code Online (Sandbox Code Playgroud)

clojure阅读器使用源文件中的字符,并在它到达编译器之前替换#'x=> (var x).正如您在上面所看到的,spyx宏("间谍表达式")甚至看不到原始#'x表达式 - 替换已经发生.

因此我们得到:

(= #'x (var x)) => true
Run Code Online (Sandbox Code Playgroud)

你也可以尝试:

(println "type 1:  " (type (var x)))
(println "type 2:  " (type #'x))

;=> type 1:   clojure.lang.Var
;=> type 2:   clojure.lang.Var
Run Code Online (Sandbox Code Playgroud)

如果你想用玩spy,spyxspyxx宏,你将需要添加到您的project.clj:

   [tupelo "0.9.19"]
Run Code Online (Sandbox Code Playgroud)