为什么在 def 中 '@foo Cons 的 class 而不是 PersistentList?
Why is the class of '@foo Cons rather than PersistentList when inside a def?
Clojure repl 下的快速实验:
> (class '@foo)
clojure.lang.PersistentList
这或多或少是预料之中的,所以让我们将相同的表达式包装在 def
:
中
> (def x '@foo)
> (class x)
clojure.lang.Cons
我试过 def
和其他各种形式,但 '@foo
似乎是唯一触发此行为的形式。
我在一个新的 REPL 中尝试了这个并重现了这个行为。
对于您所看到的特定行为,有一个令人费解的解释。您在 Clojure reader.
中发现了一个奇特的角落
@
字符是一个“reader 宏”,即 shorthand 以下内容:
@xxx => (deref xxx)
'
字符是另一个 reader 宏,也是 shorthand 用于:
'yyy => (quote yyy)
把它们放在一起你就得到了
'@zzz => (quote (deref zzz))
所以 quote
特殊形式排在第一位。它说,“将此处包含的所有内容视为数据结构,而不是可执行代码”。
数据结构(deref zzz)
是一个包含2个符号的列表,deref
和zzz
。
关于class
字面量和Var的区别,我们看到:
user=> (def bbb '@foo)
#'user/bbb
user=> (class bbb)
clojure.lang.Cons
user=> (def ccc (quote (deref foo)))
#'user/ccc
user=> (class ccc)
clojure.lang.PersistentList
使用“面向对象”的术语,Cons
、PersistentList
、PersistentVector
和 LazySeq
都是泛型的“sub类” Clojure 中的“Seq”类型。它们都可以互换使用,上面2类中意想不到的区别是一个不重要的实现细节。
Clojure repl 下的快速实验:
> (class '@foo)
clojure.lang.PersistentList
这或多或少是预料之中的,所以让我们将相同的表达式包装在 def
:
> (def x '@foo)
> (class x)
clojure.lang.Cons
我试过 def
和其他各种形式,但 '@foo
似乎是唯一触发此行为的形式。
我在一个新的 REPL 中尝试了这个并重现了这个行为。
对于您所看到的特定行为,有一个令人费解的解释。您在 Clojure reader.
中发现了一个奇特的角落@
字符是一个“reader 宏”,即 shorthand 以下内容:
@xxx => (deref xxx)
'
字符是另一个 reader 宏,也是 shorthand 用于:
'yyy => (quote yyy)
把它们放在一起你就得到了
'@zzz => (quote (deref zzz))
所以 quote
特殊形式排在第一位。它说,“将此处包含的所有内容视为数据结构,而不是可执行代码”。
数据结构(deref zzz)
是一个包含2个符号的列表,deref
和zzz
。
关于class
字面量和Var的区别,我们看到:
user=> (def bbb '@foo)
#'user/bbb
user=> (class bbb)
clojure.lang.Cons
user=> (def ccc (quote (deref foo)))
#'user/ccc
user=> (class ccc)
clojure.lang.PersistentList
使用“面向对象”的术语,Cons
、PersistentList
、PersistentVector
和 LazySeq
都是泛型的“sub类” Clojure 中的“Seq”类型。它们都可以互换使用,上面2类中意想不到的区别是一个不重要的实现细节。