引用混乱

tjb*_*tjb 3 clojure

为什么这一系列的clojure命令返回false而不是true?声明1"C"和2"(引用C)"的结果有什么区别?

; SLIME 2009-03-04
user> ('A 'B 'C)
C
user> (last '('A 'B 'C))
(quote C)
user> (= ('A 'B 'C) (last '('A 'B 'C)))
false
Run Code Online (Sandbox Code Playgroud)

这个问题有点类似于clojure的语法引用如何工作的?

mic*_*kig 7

在Clojure(和其他Lisps)中,这'是表单的快捷方式(quote ...).所以,当Clojure看到这个:

('A 'B 'C)
Run Code Online (Sandbox Code Playgroud)

被读者"翻译"成:

((quote A) (quote B) (quote C))
Run Code Online (Sandbox Code Playgroud)

这些引用形式中的每一个都评估为符号,因此(quote A)评估为名为A的符号.在Clojure中,符号是函数并且可以应用,因此((quote A) (quote B) (quote C))实际上是函数调用.来自文档:

"符号就像关键字一样,为一个参数(一个映射)的invoke()实现IFn,带有可选的第二个参数(默认值).例如('mysym my-hash-map:none)表示与(get)相同my-hash-map'mysym:none)."

所以会发生什么是C默认值,这就是它返回的原因.

同时,这个

'('A 'B 'C)
Run Code Online (Sandbox Code Playgroud)

由读者翻译成

(quote ((quote A) (quote B) (quote C)))
Run Code Online (Sandbox Code Playgroud)

这实际上是三个元素的列表,每个元素都是两个元素的列表,符号quote和另一个符号(在本例A中为B,C).

所以,(last '('A 'B 'C))实际上(quote C).这就是这两个结果之间的区别,C是名称为C的符号,(quote C)而是两个元素的列表.

你可以确认一下:

user=> (class ('A 'B 'C))
clojure.lang.Symbol
user=> (class (last '('A 'B 'C)))
clojure.lang.PersistentList
user=> 
Run Code Online (Sandbox Code Playgroud)

希望很清楚!